Flutter Impeller
impeller::testing Namespace Reference

Classes

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

Typedefs

using AiksTest = AiksPlayground
 
using AiksCanvasTest = ::testing::Test
 
using DisplayListTest = DlPlayground
 
using EntityTest = EntityPlayground
 
using HostBufferTest = EntityPlayground
 
using EntityPassTargetTest = EntityPlayground
 
using RenderTargetCacheTest = EntityPlayground
 
using AllocatorMTLTest = PlaygroundTest
 
using DriverInfoVKTest = PlaygroundTest
 
using RendererTest = PlaygroundTest
 
using BlitPassTest = PlaygroundTest
 
using ComputeTest = ComputePlaygroundTest
 
using DeviceBufferTest = Playground
 
using RuntimeStageTest = RuntimeStagePlayground
 
using TypographerTest = PlaygroundTest
 

Functions

 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, BlendModePlusAlphaWideGamut)
 
 TEST_P (AiksTest, BlendModePlusAlphaColorFilterWideGamut)
 
static BlendModeSelection GetBlendModeSelection ()
 
 TEST_P (AiksTest, ColorWheel)
 
 TEST_P (AiksTest, ForegroundBlendSubpassCollapseOptimization)
 
 TEST_P (AiksTest, ClearBlend)
 
static Picture BlendModeTest (Vector2 content_scale, BlendMode blend_mode, const std::shared_ptr< Image > &src_image, const std::shared_ptr< Image > &dst_image, Scalar src_alpha)
 
 TEST_P (AiksTest, CanDrawPaintMultipleTimesInteractive)
 
 TEST_P (AiksTest, ForegroundPipelineBlendAppliesTransformCorrectly)
 
 TEST_P (AiksTest, ForegroundAdvancedBlendAppliesTransformCorrectly)
 
 TEST_P (AiksTest, FramebufferAdvancedBlendCoverage)
 
 TEST_P (AiksTest, CanRenderMaskBlurHugeSigma)
 
 TEST_P (AiksTest, CanRenderForegroundBlendWithMaskBlur)
 
 TEST_P (AiksTest, CanRenderForegroundAdvancedBlendWithMaskBlur)
 
 TEST_P (AiksTest, CanRenderBackdropBlurInteractive)
 
 TEST_P (AiksTest, CanRenderBackdropBlur)
 
 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, BlurredRectangleWithShader)
 
 TEST_P (AiksTest, MaskBlurWithZeroSigmaIsSkipped)
 
static Picture MaskBlurVariantTest (const AiksTest &test_context, const MaskBlurTestConfig &config)
 
 TEST_P (AiksTest, GaussianBlurAtPeripheryVertical)
 
 TEST_P (AiksTest, GaussianBlurAtPeripheryHorizontal)
 
 TEST_P (AiksTest, GaussianBlurWithoutDecalSupport)
 
 TEST_P (AiksTest, GaussianBlurOneDimension)
 
 TEST_P (AiksTest, GaussianBlurRotatedAndClipped)
 
 TEST_P (AiksTest, GaussianBlurScaledAndClipped)
 
 TEST_P (AiksTest, GaussianBlurRotatedAndClippedInteractive)
 
 TEST_P (AiksTest, GaussianBlurRotatedNonUniform)
 
 TEST_P (AiksTest, GaussianBlurSolidColorTinyMipMap)
 
 TEST_P (AiksTest, GaussianBlurBackdropTinyMipMap)
 
 TEST_P (AiksTest, GaussianBlurAnimatedBackdrop)
 
 TEST_P (AiksTest, GaussianBlurStyleInnerGradient)
 
 TEST_P (AiksTest, GaussianBlurStyleSolidGradient)
 
 TEST_P (AiksTest, GaussianBlurStyleOuterGradient)
 
 TEST_P (AiksTest, GaussianBlurStyleInner)
 
 TEST_P (AiksTest, GaussianBlurStyleOuter)
 
 TEST_P (AiksTest, GaussianBlurStyleSolid)
 
 TEST_P (AiksTest, MaskBlurTexture)
 
 TEST_P (AiksTest, GuassianBlurUpdatesMipmapContents)
 
 TEST_P (AiksTest, GaussianBlurSetsMipCountOnPass)
 
 TEST_P (AiksTest, GaussianBlurAllocatesCorrectMipCountRenderTarget)
 
 TEST_P (AiksTest, GaussianBlurMipMapNestedLayer)
 
 TEST_P (AiksTest, GaussianBlurMipMapImageFilter)
 
 TEST_P (AiksTest, GaussianBlurMipMapSolidColor)
 
 TEST_P (AiksTest, MaskBlurDoesntStretchContents)
 
 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 (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, CanRenderDifferencePaths)
 
 TEST_P (AiksTest, CanDrawAnOpenPath)
 
 TEST_P (AiksTest, CanDrawAnOpenPathThatIsntARect)
 
 TEST_P (AiksTest, SolidStrokesRenderCorrectly)
 
 TEST_P (AiksTest, DrawLinesRenderCorrectly)
 
 TEST_P (AiksTest, DrawRectStrokesRenderCorrectly)
 
 TEST_P (AiksTest, DrawRectStrokesWithBevelJoinRenderCorrectly)
 
 TEST_P (AiksTest, CanDrawMultiContourConvexPath)
 
 TEST_P (AiksTest, ArcWithZeroSweepAndBlur)
 
 TEST_P (AiksTest, CanRenderClips)
 
 TEST_P (AiksTest, CanRenderOverlappingMultiContourPath)
 
 INSTANTIATE_PLAYGROUND_SUITE (AiksTest)
 
 TEST_P (AiksTest, CanvasCTMCanBeUpdated)
 
 TEST_P (AiksTest, CanvasCanPushPopCTM)
 
 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, CanRenderSimpleClips)
 
 TEST_P (AiksTest, CanSaveLayerStandalone)
 
 TEST_P (AiksTest, CanRenderDifferentShapesWithSameColorSource)
 
 TEST_P (AiksTest, CanPictureConvertToImage)
 
 TEST_P (AiksTest, CanEmptyPictureConvertToImage)
 
 TEST_P (AiksTest, CoordinateConversionsAreCorrect)
 
 TEST_P (AiksTest, CanPerformFullScreenMSAA)
 
 TEST_P (AiksTest, CanPerformSkew)
 
 TEST_P (AiksTest, CanPerformSaveLayerWithBounds)
 
 TEST_P (AiksTest, CanPerformSaveLayerWithBoundsAndLargerIntermediateIsNotAllocated)
 
 TEST_P (AiksTest, CanRenderRoundedRectWithNonUniformRadii)
 
bool RenderTextInCanvasSkia (const std::shared_ptr< Context > &context, Canvas &canvas, const std::string &text, const std::string_view &font_fixture, TextRenderOptions options={})
 
bool RenderTextInCanvasSTB (const std::shared_ptr< Context > &context, Canvas &canvas, const std::string &text, const std::string &font_fixture, TextRenderOptions options={})
 
 TEST_P (AiksTest, CanRenderTextFrame)
 
 TEST_P (AiksTest, CanRenderTextFrameWithInvertedTransform)
 
 TEST_P (AiksTest, CanRenderStrokedTextFrame)
 
 TEST_P (AiksTest, CanRenderTextFrameWithHalfScaling)
 
 TEST_P (AiksTest, CanRenderTextFrameWithFractionScaling)
 
 TEST_P (AiksTest, CanRenderTextFrameSTB)
 
 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, CanDrawPaint)
 
 TEST_P (AiksTest, CanDrawPaintMultipleTimes)
 
 TEST_P (AiksTest, FormatWideGamut)
 
 TEST_P (AiksTest, FormatSRGB)
 
 TEST_P (AiksTest, TransformMultipliesCorrectly)
 
 TEST_P (AiksTest, FilledCirclesRenderCorrectly)
 
 TEST_P (AiksTest, StrokedCirclesRenderCorrectly)
 
 TEST_P (AiksTest, FilledEllipsesRenderCorrectly)
 
 TEST_P (AiksTest, FilledRoundRectsRenderCorrectly)
 
 TEST_P (AiksTest, SolidColorCirclesOvalsRRectsMaskBlurCorrectly)
 
 TEST_P (AiksTest, FastEllipticalRRectMaskBlursRenderCorrectly)
 
 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, PaintWithFilters)
 
 TEST_P (AiksTest, DrawPaintAbsorbsClears)
 
 TEST_P (AiksTest, ParentSaveLayerCreatesRenderPassWhenChildBackdropFilterIsPresent)
 
 TEST_P (AiksTest, DrawRectAbsorbsClears)
 
 TEST_P (AiksTest, DrawRectAbsorbsClearsNegativeRRect)
 
 TEST_P (AiksTest, DrawRectAbsorbsClearsNegativeRotation)
 
 TEST_P (AiksTest, DrawRectAbsorbsClearsNegative)
 
 TEST_P (AiksTest, ClipRectElidesNoOpClips)
 
 TEST_P (AiksTest, ClearColorOptimizationDoesNotApplyForBackdropFilters)
 
 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, ImageFilteredSaveLayerWithUnboundedContents)
 
 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, OpaqueEntitiesGetCoercedToSource)
 
 TEST_P (AiksTest, CanRenderDestructiveSaveLayer)
 
 TEST_P (AiksTest, CanRenderClippedRuntimeEffects)
 
 TEST_P (AiksTest, DrawPaintTransformsBounds)
 
 TEST_P (AiksTest, CanDrawPoints)
 
 TEST_P (AiksTest, CanDrawPointsWithTextureMap)
 
 TEST_P (AiksTest, TextForegroundShaderWithTransform)
 
 TEST_P (AiksTest, MatrixSaveLayerFilter)
 
 TEST_P (AiksTest, MatrixBackdropFilter)
 
 TEST_P (AiksTest, SolidColorApplyColorFilter)
 
 TEST_P (AiksTest, DrawScaledTextWithPerspectiveNoSaveLayer)
 
 TEST_P (AiksTest, DrawScaledTextWithPerspectiveSaveLayer)
 
 TEST_P (AiksTest, PipelineBlendSingleParameter)
 
 TEST_P (AiksTest, ReleasesTextureOnTeardown)
 
 TEST_P (AiksTest, MatrixImageFilterMagnify)
 
 TEST_P (AiksTest, MatrixImageFilterDoesntCullWhenTranslatedFromOffscreen)
 
 TEST_P (AiksTest, MatrixImageFilterDoesntCullWhenScaledAndTranslatedFromOffscreen)
 
 TEST_P (AiksTest, ClearColorOptimizationWhenSubpassIsBiggerThanParentPass)
 
 TEST_P (AiksTest, EmptySaveLayerIgnoresPaint)
 
 TEST_P (AiksTest, EmptySaveLayerRendersWithClear)
 
 TEST_P (AiksTest, SubpassWithClearColorOptimization)
 
 TEST_P (AiksTest, ImageColorSourceEffectTransform)
 
 TEST_P (AiksTest, CorrectClipDepthAssignedToEntities)
 
 TEST_P (AiksTest, CanDrawPerspectiveTransformWithClips)
 
 TEST_P (AiksTest, CanRenderClippedBackdropFilter)
 
 TEST_P (AiksTest, MipmapGenerationWorksCorrectly)
 
 TEST_P (AiksTest, StrokedPathWithMoveToThenCloseDrawnCorrectly)
 
 TEST_P (AiksTest, CanRenderTextWithLargePerspectiveTransform)
 
 TEST_P (AiksTest, SetContentsWithRegion)
 
 TEST (AiksCanvasTest, EmptyCullRect)
 
 TEST (AiksCanvasTest, InitialCullRect)
 
 TEST (AiksCanvasTest, TranslatedCullRect)
 
 TEST (AiksCanvasTest, ScaledCullRect)
 
 TEST (AiksCanvasTest, RectClipIntersectAgainstEmptyCullRect)
 
 TEST (AiksCanvasTest, RectClipDiffAgainstEmptyCullRect)
 
 TEST (AiksCanvasTest, RectClipIntersectAgainstCullRect)
 
 TEST (AiksCanvasTest, RectClipDiffAgainstNonCoveredCullRect)
 
 TEST (AiksCanvasTest, RectClipDiffAboveCullRect)
 
 TEST (AiksCanvasTest, RectClipDiffBelowCullRect)
 
 TEST (AiksCanvasTest, RectClipDiffLeftOfCullRect)
 
 TEST (AiksCanvasTest, RectClipDiffRightOfCullRect)
 
 TEST (AiksCanvasTest, RectClipDiffAgainstVCoveredCullRect)
 
 TEST (AiksCanvasTest, RectClipDiffAgainstHCoveredCullRect)
 
 TEST (AiksCanvasTest, RRectClipIntersectAgainstEmptyCullRect)
 
 TEST (AiksCanvasTest, RRectClipDiffAgainstEmptyCullRect)
 
 TEST (AiksCanvasTest, RRectClipIntersectAgainstCullRect)
 
 TEST (AiksCanvasTest, RRectClipDiffAgainstNonCoveredCullRect)
 
 TEST (AiksCanvasTest, RRectClipDiffAgainstVPartiallyCoveredCullRect)
 
 TEST (AiksCanvasTest, RRectClipDiffAgainstVFullyCoveredCullRect)
 
 TEST (AiksCanvasTest, RRectClipDiffAgainstHPartiallyCoveredCullRect)
 
 TEST (AiksCanvasTest, RRectClipDiffAgainstHFullyCoveredCullRect)
 
 TEST (AiksCanvasTest, PathClipIntersectAgainstEmptyCullRect)
 
 TEST (AiksCanvasTest, PathClipDiffAgainstEmptyCullRect)
 
 TEST (AiksCanvasTest, PathClipIntersectAgainstCullRect)
 
 TEST (AiksCanvasTest, PathClipDiffAgainstNonCoveredCullRect)
 
 TEST (AiksCanvasTest, PathClipDiffAgainstFullyCoveredCullRect)
 
 TEST (AiksCanvasTest, DisableLocalBoundsRectForFilteredSaveLayers)
 
 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_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, 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, 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, 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, DrawVerticesTextureCoordinatesWithFragmentShader)
 
 TEST_P (AiksTest, DrawVerticesTextureCoordinatesWithFragmentShaderNonZeroOrigin)
 
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, DispatcherDoesNotCullPerspectiveTransformedChildDisplayLists)
 
 TEST_P (DisplayListTest, TransparentShadowProducesCorrectColor)
 
 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)
 
template<typename Contents >
static std::optional< RectGetCoverageOfFirstEntity (const Picture &picture)
 
 TEST (DisplayListTest, RRectBoundsComputation)
 
 TEST (DisplayListTest, CircleBoundsComputation)
 
 TEST_P (DisplayListTest, DrawPaintIgnoresMaskFilter)
 
 TEST_P (DisplayListTest, DrawMaskBlursThatMightUseSaveLayers)
 
 TEST (SkiaConversionsTest, SkPointToPoint)
 
 TEST (SkiaConversionsTest, SkPointToSize)
 
 TEST (SkiaConversionsTest, ToColor)
 
 TEST (SkiaConversionsTest, GradientStopConversion)
 
 TEST (SkiaConversionsTest, GradientMissing0)
 
 TEST (SkiaConversionsTest, GradientMissingLastValue)
 
 TEST (SkiaConversionsTest, GradientStopGreaterThan1)
 
 TEST (SkiaConversionsTest, GradientConversionNonMonotonic)
 
 TEST (SkiaConversionsTest, IsNearlySimpleRRect)
 
 TEST_P (EntityTest, ClipContentsOptimizesFullScreenIntersectClips)
 
 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)
 
 TEST (FilterInputTest, IsLeaf)
 
 TEST (FilterInputTest, SetCoverageInputs)
 
 INSTANTIATE_PLAYGROUND_SUITE (MatrixFilterContentsTest)
 
 TEST (MatrixFilterContentsTest, Create)
 
 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, 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 (EntityTest, TiledTextureContentsRendersWithCorrectPipeline)
 
 TEST_P (EntityTest, TiledTextureContentsRendersWithCorrectPipelineExternalOES)
 
 TEST_P (EntityPassTargetTest, SwapWithMSAATexture)
 
 TEST_P (EntityPassTargetTest, SwapWithMSAAImplicitResolve)
 
 TEST (EntityPassClipStackTest, CanPushAndPopEntities)
 
 TEST (EntityPassClipStackTest, CanPopEntitiesSafely)
 
 TEST (EntityPassClipStackTest, CanAppendNoChange)
 
 TEST (EntityPassClipStackTest, AppendCoverageNoChange)
 
 TEST (EntityPassClipStackTest, AppendAndRestoreClipCoverage)
 
 TEST (EntityPassClipStackTest, UnbalancedRestore)
 
 TEST (EntityPassClipStackTest, ClipAndRestoreWithSubpasses)
 
 TEST_P (EntityTest, CanCreateEntity)
 
auto CreatePassWithRectPath (Rect rect, std::optional< Rect > bounds_hint, ContentBoundsPromise bounds_promise=ContentBoundsPromise::kUnknown, bool collapse=false)
 
 TEST_P (EntityTest, EntityPassRespectsUntrustedSubpassBoundsLimit)
 
 TEST_P (EntityTest, EntityPassTrustsSnugSubpassBoundsLimit)
 
 TEST_P (EntityTest, EntityPassCanMergeSubpassIntoParent)
 
 TEST_P (EntityTest, EntityPassCoverageRespectsCoverageLimit)
 
 TEST_P (EntityTest, FilterCoverageRespectsCropRect)
 
 TEST_P (EntityTest, CanDrawRect)
 
 TEST_P (EntityTest, CanDrawRRect)
 
 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, SolidFillShouldRenderIsCorrect)
 
 TEST_P (EntityTest, DoesNotCullEntitiesByDefault)
 
 TEST_P (EntityTest, ClipContentsShouldRenderIsCorrect)
 
 TEST_P (EntityTest, ClipContentsGetClipCoverageIsCorrect)
 
 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, InheritOpacityTest)
 
 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, AdvancedBlendCoverageHintIsNotResetByEntityPass)
 
 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 (EntityGeometryTest, RectGeometryCoversArea)
 
 TEST (EntityGeometryTest, FillPathGeometryCoversArea)
 
 TEST (EntityGeometryTest, FillPathGeometryCoversAreaNoInnerRect)
 
 TEST (EntityGeometryTest, LineGeometryCoverage)
 
 TEST (EntityGeometryTest, RoundRectGeometryCoversArea)
 
 TEST (EntityGeometryTest, GeometryResultHasReasonableDefaults)
 
 TEST (EntityGeometryTest, AlphaCoverageStrokePaths)
 
 TEST_P (RenderTargetCacheTest, CachesUsedTexturesAcrossFrames)
 
 TEST_P (RenderTargetCacheTest, DoesNotPersistFailedAllocations)
 
 TEST_P (RenderTargetCacheTest, CachedTextureGetsNewAttachmentConfig)
 
 TEST_P (RenderTargetCacheTest, CreateWithEmptySize)
 
 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, MatrixGetMaxBasisLength)
 
 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, 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, HasPerspective2D)
 
 TEST (MatrixTest, HasPerspective)
 
 TEST (MatrixTest, HasTranslation)
 
 TEST (MatrixTest, IsAligned2D)
 
 TEST (MatrixTest, IsAligned)
 
 TEST (MatrixTest, TransformHomogenous)
 
 TEST (PathTest, CubicPathComponentPolylineDoesNotIncludePointOne)
 
 TEST (PathTest, PathCreatePolyLineDoesNotDuplicatePoints)
 
 TEST (PathTest, PathBuilderSetsCorrectContourPropertiesForAddCommands)
 
 TEST (PathTest, PathCreatePolylineGeneratesCorrectContourData)
 
 TEST (PathTest, PolylineGetContourPointBoundsReturnsCorrectRanges)
 
 TEST (PathTest, PathAddRectPolylineHasCorrectContourData)
 
 TEST (PathTest, PathPolylineDuplicatesAreRemovedForSameContour)
 
 TEST (PathTest, PolylineBufferReuse)
 
 TEST (PathTest, PolylineFailsWithNullptrBuffer)
 
 TEST (PathTest, PathShifting)
 
 TEST (PathTest, PathBuilderWillComputeBounds)
 
 TEST (PathTest, PathHorizontalLine)
 
 TEST (PathTest, PathVerticalLine)
 
 TEST (PathTest, QuadradicPath)
 
 TEST (PathTest, CubicPath)
 
 TEST (PathTest, BoundingBoxCubic)
 
 TEST (PathTest, BoundingBoxOfCompositePathIsCorrect)
 
 TEST (PathTest, ExtremaOfCubicPathComponentIsCorrect)
 
 TEST (PathTest, PathGetBoundingBoxForCubicWithNoDerivativeRootsIsCorrect)
 
 TEST (PathTest, EmptyPath)
 
 TEST (PathTest, SimplePath)
 
 TEST (PathTest, RepeatCloseDoesNotAddNewLines)
 
 TEST (PathTest, CloseAfterMoveDoesNotAddNewLines)
 
 TEST (PathTest, CloseAtOriginDoesNotAddNewLineSegment)
 
 TEST (PathTest, CanBeCloned)
 
 TEST (PathTest, PathBuilderDoesNotMutateCopiedPaths)
 
 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, 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 (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)
 
 INSTANTIATE_METAL_PLAYGROUND_SUITE (AllocatorMTLTest)
 
 TEST_P (AllocatorMTLTest, DebugTraceMemoryStatistics)
 
 TEST (TextureMTL, CreateFromDrawable)
 
 TEST (AllocatorVKTest, ToVKImageUsageFlags)
 
 TEST (AllocatorVKTest, MemoryTypeSelectionSingleHeap)
 
 TEST (AllocatorVKTest, MemoryTypeSelectionTwoHeap)
 
 TEST (CommandEncoderVKTest, DeleteEncoderAfterThreadDies)
 
 TEST (CommandEncoderVKTest, CleanupAfterSubmit)
 
 TEST (CommandPoolRecyclerVKTest, GetsACommandPoolPerThread)
 
 TEST (CommandPoolRecyclerVKTest, GetsTheSameCommandPoolOnSameThread)
 
 TEST (CommandPoolRecyclerVKTest, ReclaimMakesCommandPoolAvailable)
 
 TEST (CommandPoolRecyclerVKTest, CommandBuffersAreRecycled)
 
 TEST (ContextVKTest, CommonHardwareConcurrencyConfigurations)
 
 TEST (ContextVKTest, DeletesCommandPools)
 
 TEST (ContextVKTest, DeletesCommandPoolsOnAllThreads)
 
 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 (DescriptorPoolRecyclerVKTest, GetDescriptorPoolRecyclerCreatesNewPools)
 
 TEST (DescriptorPoolRecyclerVKTest, ReclaimMakesDescriptorPoolAvailable)
 
 TEST (DescriptorPoolRecyclerVKTest, ReclaimDropsDescriptorPoolIfSizeIsExceeded)
 
 INSTANTIATE_VULKAN_PLAYGROUND_SUITE (DriverInfoVKTest)
 
 TEST_P (DriverInfoVKTest, CanQueryDriverInfo)
 
 TEST_P (DriverInfoVKTest, CanDumpToLog)
 
 TEST (FenceWaiterVKTest, IgnoresNullFence)
 
 TEST (FenceWaiterVKTest, IgnoresNullCallback)
 
 TEST (FenceWaiterVKTest, ExecutesFenceCallback)
 
 TEST (FenceWaiterVKTest, ExecutesFenceCallbackX2)
 
 TEST (FenceWaiterVKTest, ExecutesNewFenceThenOldFence)
 
 TEST (FenceWaiterVKTest, AddFenceDoesNothingIfTerminating)
 
 TEST (FenceWaiterVKTest, InProgressFencesStillWaitIfTerminated)
 
 TEST (RenderPassBuilder, CreatesRenderPassWithNoDepthStencil)
 
 TEST (RenderPassBuilder, CreatesRenderPassWithCombinedDepthStencil)
 
 TEST (RenderPassBuilder, CreatesRenderPassWithOnlyStencil)
 
 TEST (RenderPassBuilder, CreatesMSAAResolveWithCorrectStore)
 
 TEST_P (RendererTest, CachesRenderPassAndFramebuffer)
 
 TEST (ResourceManagerVKTest, CreatesANewInstance)
 
 TEST (ResourceManagerVKTest, ReclaimMovesAResourceAndDestroysIt)
 
 TEST (ResourceManagerVKTest, TerminatesWhenOutOfScope)
 
 TEST (ResourceManagerVKTest, IsThreadSafe)
 
 INSTANTIATE_PLAYGROUND_SUITE (BlitPassTest)
 
 TEST_P (BlitPassTest, BlitAcrossDifferentPixelFormatsFails)
 
 TEST_P (BlitPassTest, BlitAcrossDifferentSampleCountsFails)
 
 TEST_P (BlitPassTest, BlitPassesForMatchingFormats)
 
 TEST_P (BlitPassTest, ChecksInvalidSliceParameters)
 
 TEST_P (BlitPassTest, CanBlitSmallRegionToUninitializedTexture)
 
 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)
 
 TEST (CapabilitiesTest, DefaultColorFormat)
 
 TEST (CapabilitiesTest, DefaultStencilFormat)
 
 TEST (CapabilitiesTest, DefaultDepthStencilFormat)
 
 TEST (CapabilitiesTest, DefaultGlyphAtlasFormat)
 
 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, UniformBindFailsForInvalidHostBufferOffset)
 
 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)
 
 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 (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)
 
 TEST (TessellatorTest, ChecksConcurrentPolylineUsage)
 
static std::shared_ptr< GlyphAtlasCreateGlyphAtlas (Context &context, const TypographerContext *typographer_context, HostBuffer &host_buffer, GlyphAtlas::Type type, Scalar scale, const std::shared_ptr< GlyphAtlasContext > &atlas_context, const TextFrame &frame)
 
static std::shared_ptr< GlyphAtlasCreateGlyphAtlas (Context &context, const TypographerContext *typographer_context, HostBuffer &host_buffer, GlyphAtlas::Type type, Scalar scale, const std::shared_ptr< GlyphAtlasContext > &atlas_context, const std::vector< std::shared_ptr< TextFrame >> &frames, const std::vector< 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)
 

Variables

static const std::map< std::string, MaskBlurTestConfigkPaintVariations
 
static constexpr std::string_view kFontFixture
 
std::vector< Pointgolden_cubic_and_quad_points
 

Typedef Documentation

◆ AiksCanvasTest

using impeller::testing::AiksCanvasTest = typedef ::testing::Test

Definition at line 16 of file canvas_unittests.cc.

◆ AiksTest

Definition at line 17 of file aiks_unittests.h.

◆ AllocatorMTLTest

◆ BlitPassTest

Definition at line 16 of file blit_pass_unittests.cc.

◆ ComputeTest

Definition at line 21 of file compute_unittests.cc.

◆ DeviceBufferTest

Definition at line 12 of file device_buffer_unittests.cc.

◆ DisplayListTest

Definition at line 46 of file dl_unittests.cc.

◆ DriverInfoVKTest

◆ EntityPassTargetTest

◆ EntityTest

◆ HostBufferTest

◆ RendererTest

◆ RenderTargetCacheTest

◆ RuntimeStageTest

◆ 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 Picture impeller::testing::BlendModeTest ( Vector2  content_scale,
BlendMode  blend_mode,
const std::shared_ptr< Image > &  src_image,
const std::shared_ptr< Image > &  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 368 of file aiks_blend_unittests.cc.

372  {
373  if (AiksTest::ImGuiBegin("Controls", nullptr,
374  ImGuiWindowFlags_AlwaysAutoResize)) {
375  ImGui::SliderFloat("Source alpha", &src_alpha, 0, 1);
376  ImGui::End();
377  }
378 
379  Color destination_color = Color::CornflowerBlue().WithAlpha(0.75);
380  auto source_colors = std::vector<Color>({Color::White().WithAlpha(0.75),
381  Color::LimeGreen().WithAlpha(0.75),
382  Color::Black().WithAlpha(0.75)});
383 
384  Canvas canvas;
385  canvas.DrawPaint({.color = Color::Black()});
386  // TODO(bdero): Why does this cause the left image to double scale on high DPI
387  // displays.
388  // canvas.Scale(content_scale);
389 
390  //----------------------------------------------------------------------------
391  /// 1. Save layer blending (top squares).
392  ///
393 
394  canvas.Save();
395  for (const auto& color : source_colors) {
396  canvas.Save();
397  {
398  canvas.ClipRect(Rect::MakeXYWH(25, 25, 100, 100));
399  // Perform the blend in a SaveLayer so that the initial backdrop color is
400  // fully transparent black. SourceOver blend the result onto the parent
401  // pass.
402  canvas.SaveLayer({});
403  {
404  canvas.DrawPaint({.color = destination_color});
405  // Draw the source color in an offscreen pass and blend it to the parent
406  // pass.
407  canvas.SaveLayer({.blend_mode = blend_mode});
408  { //
409  canvas.DrawRect(Rect::MakeXYWH(25, 25, 100, 100), {.color = color});
410  }
411  canvas.Restore();
412  }
413  canvas.Restore();
414  }
415  canvas.Restore();
416  canvas.Translate(Vector2(100, 0));
417  }
418  canvas.RestoreToCount(0);
419 
420  //----------------------------------------------------------------------------
421  /// 2. CPU blend modes (bottom squares).
422  ///
423 
424  canvas.Save();
425  canvas.Translate({0, 100});
426  // Perform the blend in a SaveLayer so that the initial backdrop color is
427  // fully transparent black. SourceOver blend the result onto the parent pass.
428  canvas.SaveLayer({});
429  for (const auto& color : source_colors) {
430  // Simply write the CPU blended color to the pass.
431  canvas.DrawRect(Rect::MakeXYWH(25, 25, 100, 100),
432  {.color = destination_color.Blend(color, blend_mode),
433  .blend_mode = BlendMode::kSourceOver});
434  canvas.Translate(Vector2(100, 0));
435  }
436  canvas.Restore();
437  canvas.Restore();
438 
439  //----------------------------------------------------------------------------
440  /// 3. Image blending (bottom images).
441  ///
442  /// Compare these results with the images in the Flutter blend mode
443  /// documentation: https://api.flutter.dev/flutter/dart-ui/BlendMode.html
444  ///
445 
446  canvas.Translate({0, 250});
447 
448  // Draw grid behind the images.
449  canvas.DrawRect(Rect::MakeLTRB(0, 0, 800, 400),
450  {.color = Color::MakeRGBA8(41, 41, 41, 255)});
451  Paint square_paint = {.color = Color::MakeRGBA8(15, 15, 15, 255)};
452  for (int y = 0; y < 400 / 8; y++) {
453  for (int x = 0; x < 800 / 16; x++) {
454  canvas.DrawRect(Rect::MakeXYWH(x * 16 + (y % 2) * 8, y * 8, 8, 8),
455  square_paint);
456  }
457  }
458 
459  // Uploaded image source (left image).
460  canvas.Save();
461  canvas.SaveLayer({.blend_mode = BlendMode::kSourceOver});
462  {
463  canvas.DrawImage(dst_image, {0, 0},
464  {
465  .blend_mode = BlendMode::kSourceOver,
466  });
467  canvas.DrawImage(src_image, {0, 0},
468  {
469  .color = Color::White().WithAlpha(src_alpha),
470  .blend_mode = blend_mode,
471  });
472  }
473  canvas.Restore();
474  canvas.Restore();
475 
476  // Rendered image source (right image).
477  canvas.Save();
478  canvas.SaveLayer({.blend_mode = BlendMode::kSourceOver});
479  {
480  canvas.DrawImage(dst_image, {400, 0},
481  {.blend_mode = BlendMode::kSourceOver});
482  canvas.SaveLayer({.color = Color::White().WithAlpha(src_alpha),
483  .blend_mode = blend_mode});
484  {
485  canvas.DrawImage(src_image, {400, 0},
486  {.blend_mode = BlendMode::kSourceOver});
487  }
488  canvas.Restore();
489  }
490  canvas.Restore();
491  canvas.Restore();
492 
493  return canvas.EndRecordingAsPicture();
494 }

References impeller::Color::Black(), impeller::Color::Blend(), color, impeller::Paint::color, impeller::Color::CornflowerBlue(), impeller::Canvas::DrawPaint(), impeller::AiksPlayground::ImGuiBegin(), impeller::kSourceOver, impeller::Color::LimeGreen(), impeller::TRect< Scalar >::MakeLTRB(), impeller::Color::MakeRGBA8(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Color::White(), and impeller::Color::WithAlpha().

◆ CanRenderConicalGradientWithDithering()

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

Definition at line 167 of file aiks_dl_gradient_unittests.cc.

167  {
168  DisplayListBuilder builder;
169  builder.Scale(aiks_test->GetContentScale().x, aiks_test->GetContentScale().y);
170  DlPaint paint;
171  builder.Translate(100.0, 100.0);
172 
173  // #FFF -> #000
174  std::vector<DlColor> colors = {DlColor(Color{1.0, 1.0, 1.0, 1.0}.ToARGB()),
175  DlColor(Color{0.0, 0.0, 0.0, 1.0}.ToARGB())};
176  std::vector<Scalar> stops = {0.0, 1.0};
177 
178  paint.setColorSource(DlColorSource::MakeConical({0, 1}, 0, {100, 100}, 100, 2,
179  colors.data(), stops.data(),
180  DlTileMode::kMirror));
181 
182  builder.DrawRect(SkRect::MakeXYWH(0, 0, 600, 600), paint);
183  ASSERT_TRUE(aiks_test->OpenPlaygroundHere(builder.Build()));
184 }

References impeller::Playground::GetContentScale(), impeller::AiksPlayground::OpenPlaygroundHere(), paint, 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 104 of file aiks_dl_gradient_unittests.cc.

104  {
105  DisplayListBuilder builder;
106  DlPaint paint;
107  builder.Translate(100.0, 100.0);
108 
109  // 0xffcccccc --> 0xff333333, taken from
110  // https://github.com/flutter/flutter/issues/118073#issue-1521699748
111  std::vector<DlColor> colors = {DlColor(0xFFCCCCCC), DlColor(0xFF333333)};
112  std::vector<Scalar> stops = {0.0, 1.0};
113 
114  paint.setColorSource(DlColorSource::MakeLinear(
115  {0, 0}, {800, 500}, 2, colors.data(), stops.data(), DlTileMode::kClamp));
116  builder.DrawRect(SkRect::MakeXYWH(0, 0, 800, 500), paint);
117  ASSERT_TRUE(aiks_test->OpenPlaygroundHere(builder.Build()));
118 }

References impeller::AiksPlayground::OpenPlaygroundHere(), and paint.

Referenced by TEST_P().

◆ CanRenderRadialGradientWithDithering()

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

Definition at line 124 of file aiks_dl_gradient_unittests.cc.

124  {
125  DisplayListBuilder builder;
126  DlPaint paint;
127  builder.Translate(100.0, 100.0);
128 
129  // #FFF -> #000
130  std::vector<DlColor> colors = {DlColor(Color{1.0, 1.0, 1.0, 1.0}.ToARGB()),
131  DlColor(Color{0.0, 0.0, 0.0, 1.0}.ToARGB())};
132  std::vector<Scalar> stops = {0.0, 1.0};
133 
134  paint.setColorSource(DlColorSource::MakeRadial(
135  {600, 600}, 600, 2, colors.data(), stops.data(), DlTileMode::kClamp));
136  builder.DrawRect(SkRect::MakeXYWH(0, 0, 1200, 1200), paint);
137  ASSERT_TRUE(aiks_test->OpenPlaygroundHere(builder.Build()));
138 }

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

Referenced by TEST_P().

◆ CanRenderSweepGradientWithDithering()

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

Definition at line 144 of file aiks_dl_gradient_unittests.cc.

144  {
145  DisplayListBuilder builder;
146  builder.Scale(aiks_test->GetContentScale().x, aiks_test->GetContentScale().y);
147  DlPaint paint;
148  builder.Translate(100.0, 100.0);
149 
150  // #FFF -> #000
151  std::vector<DlColor> colors = {DlColor(Color{1.0, 1.0, 1.0, 1.0}.ToARGB()),
152  DlColor(Color{0.0, 0.0, 0.0, 1.0}.ToARGB())};
153  std::vector<Scalar> stops = {0.0, 1.0};
154 
155  paint.setColorSource(DlColorSource::MakeSweep(
156  {100, 100}, /*start=*/45, /*end=*/135, 2, colors.data(), stops.data(),
157  DlTileMode::kMirror));
158 
159  builder.DrawRect(SkRect::MakeXYWH(0, 0, 600, 600), paint);
160  ASSERT_TRUE(aiks_test->OpenPlaygroundHere(builder.Build()));
161 }

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

Referenced by TEST_P().

◆ CAPABILITY_TEST() [1/9]

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

◆ CAPABILITY_TEST() [2/9]

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

◆ CAPABILITY_TEST() [3/9]

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

◆ CAPABILITY_TEST() [4/9]

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

◆ CAPABILITY_TEST() [5/9]

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

◆ CAPABILITY_TEST() [6/9]

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

◆ CAPABILITY_TEST() [7/9]

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

◆ CAPABILITY_TEST() [8/9]

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

◆ CAPABILITY_TEST() [9/9]

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

◆ CompareFunctionUI()

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

Definition at line 1184 of file renderer_unittests.cc.

1184  {
1185  static CompareFunctionUIData data;
1186  return data;
1187 }

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 1376 of file renderer_unittests.cc.

1377  {
1378  using TexturePipelineBuilder = PipelineBuilder<VertexShader, FragmentShader>;
1379  auto pipeline_desc =
1380  TexturePipelineBuilder::MakeDefaultPipelineDescriptor(*context);
1381  if (!pipeline_desc.has_value()) {
1382  return nullptr;
1383  }
1384  pipeline_desc->SetSampleCount(SampleCount::kCount4);
1385  pipeline_desc->SetStencilAttachmentDescriptors(std::nullopt);
1386  auto pipeline =
1387  context->GetPipelineLibrary()->GetPipeline(pipeline_desc).Get();
1388  if (!pipeline || !pipeline->IsValid()) {
1389  return nullptr;
1390  }
1391  return pipeline;
1392 }

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,
Scalar  scale,
const std::shared_ptr< GlyphAtlasContext > &  atlas_context,
const std::vector< std::shared_ptr< TextFrame >> &  frames,
const std::vector< GlyphProperties > &  properties 
)
static

Definition at line 46 of file typographer_unittests.cc.

54  {
55  FontGlyphMap font_glyph_map;
56  size_t offset = 0;
57  for (auto& frame : frames) {
58  frame->CollectUniqueFontGlyphPairs(font_glyph_map, scale, {0, 0},
59  properties[offset++]);
60  }
61  return typographer_context->CreateGlyphAtlas(context, type, host_buffer,
62  atlas_context, font_glyph_map);
63 }

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

◆ CreateGlyphAtlas() [2/2]

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

Definition at line 32 of file typographer_unittests.cc.

39  {
40  FontGlyphMap font_glyph_map;
41  frame.CollectUniqueFontGlyphPairs(font_glyph_map, scale, {0, 0}, {});
42  return typographer_context->CreateGlyphAtlas(context, type, host_buffer,
43  atlas_context, font_glyph_map);
44 }

References impeller::TextFrame::CollectUniqueFontGlyphPairs(), impeller::TypographerContext::CreateGlyphAtlas(), scale, and type.

Referenced by TEST_P().

◆ 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().

◆ CreatePassWithRectPath()

auto impeller::testing::CreatePassWithRectPath ( Rect  rect,
std::optional< Rect bounds_hint,
ContentBoundsPromise  bounds_promise = ContentBoundsPromise::kUnknown,
bool  collapse = false 
)

Definition at line 110 of file entity_unittests.cc.

114  {
115  auto subpass = std::make_unique<EntityPass>();
116  Entity entity;
117  entity.SetContents(SolidColorContents::Make(
118  PathBuilder{}.AddRect(rect).TakePath(), Color::Red()));
119  subpass->AddEntity(std::move(entity));
120  subpass->SetDelegate(std::make_unique<TestPassDelegate>(collapse));
121  subpass->SetBoundsLimit(bounds_hint, bounds_promise);
122  return subpass;
123 }

References impeller::PathBuilder::AddRect(), impeller::SolidColorContents::Make(), impeller::Color::Red(), and impeller::Entity::SetContents().

Referenced by TEST_P().

◆ 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().

◆ CreateTestYUVTextures()

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

Definition at line 1855 of file entity_unittests.cc.

1857  {
1858  Vector3 red = {244.0 / 255.0, 67.0 / 255.0, 54.0 / 255.0};
1859  Vector3 green = {76.0 / 255.0, 175.0 / 255.0, 80.0 / 255.0};
1860  Vector3 blue = {33.0 / 255.0, 150.0 / 255.0, 243.0 / 255.0};
1861  Vector3 white = {1.0, 1.0, 1.0};
1862  Vector3 red_yuv = RGBToYUV(red, yuv_color_space);
1863  Vector3 green_yuv = RGBToYUV(green, yuv_color_space);
1864  Vector3 blue_yuv = RGBToYUV(blue, yuv_color_space);
1865  Vector3 white_yuv = RGBToYUV(white, yuv_color_space);
1866  std::vector<Vector3> yuvs{red_yuv, green_yuv, blue_yuv, white_yuv};
1867  std::vector<uint8_t> y_data;
1868  std::vector<uint8_t> uv_data;
1869  for (int i = 0; i < 4; i++) {
1870  auto yuv = yuvs[i];
1871  uint8_t y = std::round(yuv.x * 255.0);
1872  uint8_t u = std::round(yuv.y * 255.0);
1873  uint8_t v = std::round(yuv.z * 255.0);
1874  for (int j = 0; j < 16; j++) {
1875  y_data.push_back(y);
1876  }
1877  for (int j = 0; j < 8; j++) {
1878  uv_data.push_back(j % 2 == 0 ? u : v);
1879  }
1880  }
1881  auto cmd_buffer = context->CreateCommandBuffer();
1882  auto blit_pass = cmd_buffer->CreateBlitPass();
1883 
1884  impeller::TextureDescriptor y_texture_descriptor;
1885  y_texture_descriptor.storage_mode = impeller::StorageMode::kHostVisible;
1886  y_texture_descriptor.format = PixelFormat::kR8UNormInt;
1887  y_texture_descriptor.size = {8, 8};
1888  auto y_texture =
1889  context->GetResourceAllocator()->CreateTexture(y_texture_descriptor);
1890  auto y_mapping = std::make_shared<fml::DataMapping>(y_data);
1891  auto y_mapping_buffer =
1892  context->GetResourceAllocator()->CreateBufferWithCopy(*y_mapping);
1893 
1894  blit_pass->AddCopy(DeviceBuffer::AsBufferView(y_mapping_buffer), y_texture);
1895 
1896  impeller::TextureDescriptor uv_texture_descriptor;
1897  uv_texture_descriptor.storage_mode = impeller::StorageMode::kHostVisible;
1898  uv_texture_descriptor.format = PixelFormat::kR8G8UNormInt;
1899  uv_texture_descriptor.size = {4, 4};
1900  auto uv_texture =
1901  context->GetResourceAllocator()->CreateTexture(uv_texture_descriptor);
1902  auto uv_mapping = std::make_shared<fml::DataMapping>(uv_data);
1903  auto uv_mapping_buffer =
1904  context->GetResourceAllocator()->CreateBufferWithCopy(*uv_mapping);
1905 
1906  blit_pass->AddCopy(DeviceBuffer::AsBufferView(uv_mapping_buffer), uv_texture);
1907 
1908  if (!blit_pass->EncodeCommands(context->GetResourceAllocator()) ||
1909  !context->GetCommandQueue()->Submit({cmd_buffer}).ok()) {
1910  FML_DLOG(ERROR) << "Could not copy contents into Y/UV texture.";
1911  }
1912 
1913  return {y_texture, uv_texture};
1914 }

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().

◆ flip_lr()

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

Definition at line 1279 of file rect_unittests.cc.

1279  {
1280  return R::MakeLTRB(rect.GetRight(), rect.GetTop(), //
1281  rect.GetLeft(), rect.GetBottom());
1282 }

Referenced by flip_lrtb(), and TEST().

◆ flip_lrtb()

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

Definition at line 1291 of file rect_unittests.cc.

1291  {
1292  return flip_lr(flip_tb(rect));
1293 }

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 1285 of file rect_unittests.cc.

1285  {
1286  return R::MakeLTRB(rect.GetLeft(), rect.GetBottom(), //
1287  rect.GetRight(), rect.GetTop());
1288 }

Referenced by flip_lrtb(), and TEST().

◆ GetBlendModeSelection()

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

Definition at line 188 of file aiks_blend_unittests.cc.

188  {
189  std::vector<const char*> blend_mode_names;
190  std::vector<BlendMode> blend_mode_values;
191  {
192  const std::vector<std::tuple<const char*, BlendMode>> blends = {
194  assert(blends.size() ==
195  static_cast<size_t>(Entity::kLastAdvancedBlendMode) + 1);
196  for (const auto& [name, mode] : blends) {
197  blend_mode_names.push_back(name);
198  blend_mode_values.push_back(mode);
199  }
200  }
201 
202  return {blend_mode_names, blend_mode_values};
203 }

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

Referenced by TEST_P().

◆ GetCoverageOfFirstEntity()

template<typename Contents >
static std::optional<Rect> impeller::testing::GetCoverageOfFirstEntity ( const Picture picture)
static

Definition at line 1547 of file dl_unittests.cc.

1547  {
1548  std::optional<Rect> coverage;
1549  picture.pass->IterateAllEntities([&coverage](Entity& entity) {
1550  if (std::static_pointer_cast<Contents>(entity.GetContents())) {
1551  auto contents = std::static_pointer_cast<Contents>(entity.GetContents());
1552  Entity entity;
1553  coverage = contents->GetCoverage(entity);
1554  return false;
1555  }
1556  return true;
1557  });
1558  return coverage;
1559 }

References impeller::Entity::GetContents(), and impeller::Picture::pass.

◆ 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 ( BlitPassTest  )

◆ INSTANTIATE_PLAYGROUND_SUITE() [4/9]

impeller::testing::INSTANTIATE_PLAYGROUND_SUITE ( DisplayListTest  )

◆ INSTANTIATE_PLAYGROUND_SUITE() [5/9]

impeller::testing::INSTANTIATE_PLAYGROUND_SUITE ( GaussianBlurFilterContentsTest  )

◆ INSTANTIATE_PLAYGROUND_SUITE() [6/9]

impeller::testing::INSTANTIATE_PLAYGROUND_SUITE ( HostBufferTest  )

◆ INSTANTIATE_PLAYGROUND_SUITE() [7/9]

impeller::testing::INSTANTIATE_PLAYGROUND_SUITE ( MatrixFilterContentsTest  )

◆ INSTANTIATE_PLAYGROUND_SUITE() [8/9]

impeller::testing::INSTANTIATE_PLAYGROUND_SUITE ( RendererDartTest  )

◆ INSTANTIATE_PLAYGROUND_SUITE() [9/9]

impeller::testing::INSTANTIATE_PLAYGROUND_SUITE ( RuntimeStageTest  )

◆ 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().

◆ MaskBlurVariantTest()

static Picture impeller::testing::MaskBlurVariantTest ( const AiksTest test_context,
const MaskBlurTestConfig config 
)
static

Definition at line 304 of file aiks_blur_unittests.cc.

305  {
306  Canvas canvas;
307  canvas.Scale(test_context.GetContentScale());
308  canvas.Scale(Vector2{0.8f, 0.8f});
309  Paint paint;
310  paint.mask_blur_descriptor = Paint::MaskBlurDescriptor{
311  .style = FilterContents::BlurStyle::kNormal,
312  .sigma = Sigma{1},
313  };
314 
315  canvas.DrawPaint({.color = Color::AntiqueWhite()});
316 
317  paint.mask_blur_descriptor->style = config.style;
318  paint.mask_blur_descriptor->sigma = Sigma{config.sigma};
319  paint.image_filter = config.image_filter;
320  paint.invert_colors = config.invert_colors;
321  paint.blend_mode = config.blend_mode;
322 
323  const Scalar x = 50;
324  const Scalar radius = 20.0f;
325  const Scalar y_spacing = 100.0f;
326 
327  Scalar y = 50;
328  paint.color = Color::Crimson().WithAlpha(config.alpha);
329  canvas.DrawRect(Rect::MakeXYWH(x + 25 - radius / 2, y + radius / 2, //
330  radius, 60.0f - radius),
331  paint);
332 
333  y += y_spacing;
334  paint.color = Color::Blue().WithAlpha(config.alpha);
335  canvas.DrawCircle({x + 25, y + 25}, radius, paint);
336 
337  y += y_spacing;
338  paint.color = Color::Green().WithAlpha(config.alpha);
339  canvas.DrawOval(Rect::MakeXYWH(x + 25 - radius / 2, y + radius / 2, //
340  radius, 60.0f - radius),
341  paint);
342 
343  y += y_spacing;
344  paint.color = Color::Purple().WithAlpha(config.alpha);
345  canvas.DrawRRect(Rect::MakeXYWH(x, y, 60.0f, 60.0f), //
346  {radius, radius}, //
347  paint);
348 
349  y += y_spacing;
350  paint.color = Color::Orange().WithAlpha(config.alpha);
351  canvas.DrawRRect(Rect::MakeXYWH(x, y, 60.0f, 60.0f), //
352  {radius, 5.0f}, paint);
353 
354  y += y_spacing;
355  paint.color = Color::Maroon().WithAlpha(config.alpha);
356  canvas.DrawPath(PathBuilder{}
357  .MoveTo({x + 0, y + 60})
358  .LineTo({x + 30, y + 0})
359  .LineTo({x + 60, y + 60})
360  .Close()
361  .TakePath(),
362  paint);
363 
364  y += y_spacing;
365  paint.color = Color::Maroon().WithAlpha(config.alpha);
366  canvas.DrawPath(PathBuilder{}
367  .AddArc(Rect::MakeXYWH(x + 5, y, 50, 50),
368  Radians{kPi / 2}, Radians{kPi})
369  .AddArc(Rect::MakeXYWH(x + 25, y, 50, 50),
370  Radians{kPi / 2}, Radians{kPi})
371  .Close()
372  .TakePath(),
373  paint);
374 
375  return canvas.EndRecordingAsPicture();
376 }

References impeller::PathBuilder::AddArc(), impeller::testing::MaskBlurTestConfig::alpha, impeller::Color::AntiqueWhite(), impeller::testing::MaskBlurTestConfig::blend_mode, impeller::Color::Blue(), impeller::Close(), impeller::Color::Crimson(), impeller::Canvas::DrawCircle(), impeller::Canvas::DrawOval(), impeller::Canvas::DrawPaint(), impeller::Canvas::DrawPath(), impeller::Canvas::DrawRect(), impeller::Canvas::DrawRRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::Playground::GetContentScale(), impeller::Color::Green(), impeller::testing::MaskBlurTestConfig::image_filter, impeller::testing::MaskBlurTestConfig::invert_colors, impeller::FilterContents::kNormal, impeller::kPi, impeller::LineTo(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Color::Maroon(), impeller::PathBuilder::MoveTo(), impeller::Color::Orange(), paint, impeller::Color::Purple(), impeller::Canvas::Scale(), impeller::testing::MaskBlurTestConfig::sigma, impeller::Paint::MaskBlurDescriptor::style, impeller::testing::MaskBlurTestConfig::style, and impeller::Color::WithAlpha().

◆ RenderTextInCanvasSkia()

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

Definition at line 550 of file aiks_unittests.cc.

554  {}) {
555  // Draw the baseline.
556  canvas.DrawRect(
557  Rect::MakeXYWH(options.position.x - 50, options.position.y, 900, 10),
558  Paint{.color = Color::Aqua().WithAlpha(0.25)});
559 
560  // Mark the point at which the text is drawn.
561  canvas.DrawCircle(options.position, 5.0,
562  Paint{.color = Color::Red().WithAlpha(0.25)});
563 
564  // Construct the text blob.
565  auto c_font_fixture = std::string(font_fixture);
566  auto mapping = flutter::testing::OpenFixtureAsSkData(c_font_fixture.c_str());
567  if (!mapping) {
568  return false;
569  }
570  sk_sp<SkFontMgr> font_mgr = txt::GetDefaultFontManager();
571  SkFont sk_font(font_mgr->makeFromData(mapping), options.font_size);
572  auto blob = SkTextBlob::MakeFromString(text.c_str(), sk_font);
573  if (!blob) {
574  return false;
575  }
576 
577  // Create the Impeller text frame and draw it at the designated baseline.
578  auto frame = MakeTextFrameFromTextBlobSkia(blob);
579 
580  Paint text_paint;
581  text_paint.color = options.color;
582  text_paint.mask_blur_descriptor = options.mask_blur_descriptor;
583  text_paint.stroke_width = 1;
584  text_paint.style =
585  options.stroke ? Paint::Style::kStroke : Paint::Style::kFill;
586  canvas.DrawTextFrame(frame, options.position, text_paint);
587  return true;
588 }

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

◆ RenderTextInCanvasSTB()

bool impeller::testing::RenderTextInCanvasSTB ( const std::shared_ptr< Context > &  context,
Canvas canvas,
const std::string &  text,
const std::string &  font_fixture,
TextRenderOptions  options = {} 
)

Definition at line 590 of file aiks_unittests.cc.

594  {}) {
595  // Draw the baseline.
596  canvas.DrawRect(
597  Rect::MakeXYWH(options.position.x - 50, options.position.y, 900, 10),
598  Paint{.color = Color::Aqua().WithAlpha(0.25)});
599 
600  // Mark the point at which the text is drawn.
601  canvas.DrawCircle(options.position, 5.0,
602  Paint{.color = Color::Red().WithAlpha(0.25)});
603 
604  // Construct the text blob.
605  auto mapping = flutter::testing::OpenFixtureAsMapping(font_fixture.c_str());
606  if (!mapping) {
607  return false;
608  }
609  auto typeface_stb = std::make_shared<TypefaceSTB>(std::move(mapping));
610 
611  auto frame = MakeTextFrameSTB(
612  typeface_stb, Font::Metrics{.point_size = options.font_size}, text);
613 
614  Paint text_paint;
615  text_paint.color = options.color;
616  canvas.DrawTextFrame(frame, options.position, text_paint);
617  return true;
618 }

Referenced by TEST_P().

◆ RGBToYUV()

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

Definition at line 1838 of file entity_unittests.cc.

1838  {
1839  Vector3 yuv;
1840  switch (yuv_color_space) {
1841  case YUVColorSpace::kBT601FullRange:
1842  yuv.x = rgb.x * 0.299 + rgb.y * 0.587 + rgb.z * 0.114;
1843  yuv.y = rgb.x * -0.169 + rgb.y * -0.331 + rgb.z * 0.5 + 0.5;
1844  yuv.z = rgb.x * 0.5 + rgb.y * -0.419 + rgb.z * -0.081 + 0.5;
1845  break;
1846  case YUVColorSpace::kBT601LimitedRange:
1847  yuv.x = rgb.x * 0.257 + rgb.y * 0.516 + rgb.z * 0.100 + 0.063;
1848  yuv.y = rgb.x * -0.145 + rgb.y * -0.291 + rgb.z * 0.439 + 0.5;
1849  yuv.z = rgb.x * 0.429 + rgb.y * -0.368 + rgb.z * -0.071 + 0.5;
1850  break;
1851  }
1852  return yuv;
1853 }

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 1305 of file rect_unittests.cc.

1305  {
1306  Scalar nan = std::numeric_limits<Scalar>::quiet_NaN();
1307  FML_DCHECK(index >= 0 && index <= 3);
1308  Scalar x = ((index & (1 << 0)) != 0) ? nan : point.x;
1309  Scalar y = ((index & (1 << 1)) != 0) ? nan : point.y;
1310  return Point(x, y);
1311 }

References 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 1295 of file rect_unittests.cc.

1295  {
1296  Scalar nan = std::numeric_limits<Scalar>::quiet_NaN();
1297  FML_DCHECK(index >= 0 && index <= 15);
1298  Scalar l = ((index & (1 << 0)) != 0) ? nan : rect.GetLeft();
1299  Scalar t = ((index & (1 << 1)) != 0) ? nan : rect.GetTop();
1300  Scalar r = ((index & (1 << 2)) != 0) ? nan : rect.GetRight();
1301  Scalar b = ((index & (1 << 3)) != 0) ? nan : rect.GetBottom();
1302  return Rect::MakeLTRB(l, t, r, b);
1303 }

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

impeller::testing::TEST ( AiksCanvasTest  ,
DisableLocalBoundsRectForFilteredSaveLayers   
)

Definition at line 340 of file canvas_unittests.cc.

340  {
341  Rect initial_cull = Rect::MakeXYWH(0, 0, 10, 10);
342 
343  Canvas canvas(initial_cull);
344  ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
345 
346  canvas.Save();
347  canvas.SaveLayer(
348  Paint{.image_filter = ImageFilter::MakeBlur(
349  Sigma(10), Sigma(10), FilterContents::BlurStyle::kNormal,
350  Entity::TileMode::kDecal)});
351  ASSERT_FALSE(canvas.GetCurrentLocalCullingBounds().has_value());
352 
353  canvas.Restore();
354  ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
355 }

References impeller::Canvas::GetCurrentLocalCullingBounds(), impeller::Paint::image_filter, impeller::Entity::kDecal, impeller::FilterContents::kNormal, impeller::ImageFilter::MakeBlur(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Canvas::Restore(), impeller::Canvas::Save(), and impeller::Canvas::SaveLayer().

◆ TEST() [2/360]

impeller::testing::TEST ( AiksCanvasTest  ,
EmptyCullRect   
)

Definition at line 18 of file canvas_unittests.cc.

18  {
19  Canvas canvas;
20 
21  ASSERT_FALSE(canvas.GetCurrentLocalCullingBounds().has_value());
22 }

References impeller::Canvas::GetCurrentLocalCullingBounds().

◆ TEST() [3/360]

impeller::testing::TEST ( AiksCanvasTest  ,
InitialCullRect   
)

Definition at line 24 of file canvas_unittests.cc.

24  {
25  Rect initial_cull = Rect::MakeXYWH(0, 0, 10, 10);
26 
27  Canvas canvas(initial_cull);
28 
29  ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
30  ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), initial_cull);
31 }

References impeller::Canvas::GetCurrentLocalCullingBounds(), and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST() [4/360]

impeller::testing::TEST ( AiksCanvasTest  ,
PathClipDiffAgainstEmptyCullRect   
)

Definition at line 277 of file canvas_unittests.cc.

277  {
278  PathBuilder builder;
279  builder.AddRect(Rect::MakeXYWH(5, 5, 1, 1));
280  builder.AddRect(Rect::MakeXYWH(5, 14, 1, 1));
281  builder.AddRect(Rect::MakeXYWH(14, 5, 1, 1));
282  builder.AddRect(Rect::MakeXYWH(14, 14, 1, 1));
283  Path path = builder.TakePath();
284 
285  Canvas canvas;
286  canvas.ClipPath(path, Entity::ClipOperation::kDifference);
287 
288  ASSERT_FALSE(canvas.GetCurrentLocalCullingBounds().has_value());
289 }

References impeller::PathBuilder::AddRect(), impeller::Canvas::ClipPath(), impeller::Canvas::GetCurrentLocalCullingBounds(), impeller::Entity::kDifference, impeller::TRect< Scalar >::MakeXYWH(), and impeller::PathBuilder::TakePath().

◆ TEST() [5/360]

impeller::testing::TEST ( AiksCanvasTest  ,
PathClipDiffAgainstFullyCoveredCullRect   
)

Definition at line 325 of file canvas_unittests.cc.

325  {
326  Rect initial_cull = Rect::MakeXYWH(5, 5, 10, 10);
327  PathBuilder builder;
328  builder.AddRect(Rect::MakeXYWH(0, 0, 100, 100));
329  Path path = builder.TakePath();
330  // Diff clip of Paths is ignored due to complexity
331  Rect result_cull = Rect::MakeXYWH(5, 5, 10, 10);
332 
333  Canvas canvas(initial_cull);
334  canvas.ClipPath(path, Entity::ClipOperation::kDifference);
335 
336  ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
337  ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), result_cull);
338 }

References impeller::PathBuilder::AddRect(), impeller::Canvas::ClipPath(), impeller::Canvas::GetCurrentLocalCullingBounds(), impeller::Entity::kDifference, impeller::TRect< Scalar >::MakeXYWH(), and impeller::PathBuilder::TakePath().

◆ TEST() [6/360]

impeller::testing::TEST ( AiksCanvasTest  ,
PathClipDiffAgainstNonCoveredCullRect   
)

Definition at line 308 of file canvas_unittests.cc.

308  {
309  Rect initial_cull = Rect::MakeXYWH(0, 0, 10, 10);
310  PathBuilder builder;
311  builder.AddRect(Rect::MakeXYWH(5, 5, 1, 1));
312  builder.AddRect(Rect::MakeXYWH(5, 14, 1, 1));
313  builder.AddRect(Rect::MakeXYWH(14, 5, 1, 1));
314  builder.AddRect(Rect::MakeXYWH(14, 14, 1, 1));
315  Path path = builder.TakePath();
316  Rect result_cull = Rect::MakeXYWH(0, 0, 10, 10);
317 
318  Canvas canvas(initial_cull);
319  canvas.ClipPath(path, Entity::ClipOperation::kDifference);
320 
321  ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
322  ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), result_cull);
323 }

References impeller::PathBuilder::AddRect(), impeller::Canvas::ClipPath(), impeller::Canvas::GetCurrentLocalCullingBounds(), impeller::Entity::kDifference, impeller::TRect< Scalar >::MakeXYWH(), and impeller::PathBuilder::TakePath().

◆ TEST() [7/360]

impeller::testing::TEST ( AiksCanvasTest  ,
PathClipIntersectAgainstCullRect   
)

Definition at line 291 of file canvas_unittests.cc.

291  {
292  Rect initial_cull = Rect::MakeXYWH(0, 0, 10, 10);
293  PathBuilder builder;
294  builder.AddRect(Rect::MakeXYWH(5, 5, 1, 1));
295  builder.AddRect(Rect::MakeXYWH(5, 14, 1, 1));
296  builder.AddRect(Rect::MakeXYWH(14, 5, 1, 1));
297  builder.AddRect(Rect::MakeXYWH(14, 14, 1, 1));
298  Path path = builder.TakePath();
299  Rect result_cull = Rect::MakeXYWH(5, 5, 5, 5);
300 
301  Canvas canvas(initial_cull);
302  canvas.ClipPath(path, Entity::ClipOperation::kIntersect);
303 
304  ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
305  ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), result_cull);
306 }

References impeller::PathBuilder::AddRect(), impeller::Canvas::ClipPath(), impeller::Canvas::GetCurrentLocalCullingBounds(), impeller::Entity::kIntersect, impeller::TRect< Scalar >::MakeXYWH(), and impeller::PathBuilder::TakePath().

◆ TEST() [8/360]

impeller::testing::TEST ( AiksCanvasTest  ,
PathClipIntersectAgainstEmptyCullRect   
)

Definition at line 261 of file canvas_unittests.cc.

261  {
262  PathBuilder builder;
263  builder.AddRect(Rect::MakeXYWH(5, 5, 1, 1));
264  builder.AddRect(Rect::MakeXYWH(5, 14, 1, 1));
265  builder.AddRect(Rect::MakeXYWH(14, 5, 1, 1));
266  builder.AddRect(Rect::MakeXYWH(14, 14, 1, 1));
267  Path path = builder.TakePath();
268  Rect rect_clip = Rect::MakeXYWH(5, 5, 10, 10);
269 
270  Canvas canvas;
271  canvas.ClipPath(path, Entity::ClipOperation::kIntersect);
272 
273  ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
274  ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), rect_clip);
275 }

References impeller::PathBuilder::AddRect(), impeller::Canvas::ClipPath(), impeller::Canvas::GetCurrentLocalCullingBounds(), impeller::Entity::kIntersect, impeller::TRect< Scalar >::MakeXYWH(), and impeller::PathBuilder::TakePath().

◆ TEST() [9/360]

impeller::testing::TEST ( AiksCanvasTest  ,
RectClipDiffAboveCullRect   
)

Definition at line 98 of file canvas_unittests.cc.

98  {
99  Rect initial_cull = Rect::MakeXYWH(5, 5, 10, 10);
100  Rect rect_clip = Rect::MakeXYWH(0, 0, 20, 4);
101  Rect result_cull = Rect::MakeXYWH(5, 5, 10, 10);
102 
103  Canvas canvas(initial_cull);
104  canvas.ClipRect(rect_clip, Entity::ClipOperation::kDifference);
105 
106  ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
107  ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), result_cull);
108 }

References impeller::Canvas::ClipRect(), impeller::Canvas::GetCurrentLocalCullingBounds(), impeller::Entity::kDifference, and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST() [10/360]

impeller::testing::TEST ( AiksCanvasTest  ,
RectClipDiffAgainstEmptyCullRect   
)

Definition at line 65 of file canvas_unittests.cc.

65  {
66  Rect rect_clip = Rect::MakeXYWH(5, 5, 10, 10);
67 
68  Canvas canvas;
69  canvas.ClipRect(rect_clip, Entity::ClipOperation::kDifference);
70 
71  ASSERT_FALSE(canvas.GetCurrentLocalCullingBounds().has_value());
72 }

References impeller::Canvas::ClipRect(), impeller::Canvas::GetCurrentLocalCullingBounds(), impeller::Entity::kDifference, and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST() [11/360]

impeller::testing::TEST ( AiksCanvasTest  ,
RectClipDiffAgainstHCoveredCullRect   
)

Definition at line 158 of file canvas_unittests.cc.

158  {
159  Rect initial_cull = Rect::MakeXYWH(0, 0, 10, 10);
160  Rect rect_clip = Rect::MakeXYWH(0, 5, 10, 10);
161  Rect result_cull = Rect::MakeXYWH(0, 0, 10, 5);
162 
163  Canvas canvas(initial_cull);
164  canvas.ClipRect(rect_clip, Entity::ClipOperation::kDifference);
165 
166  ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
167  ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), result_cull);
168 }

References impeller::Canvas::ClipRect(), impeller::Canvas::GetCurrentLocalCullingBounds(), impeller::Entity::kDifference, and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST() [12/360]

impeller::testing::TEST ( AiksCanvasTest  ,
RectClipDiffAgainstNonCoveredCullRect   
)

Definition at line 86 of file canvas_unittests.cc.

86  {
87  Rect initial_cull = Rect::MakeXYWH(0, 0, 10, 10);
88  Rect rect_clip = Rect::MakeXYWH(5, 5, 10, 10);
89  Rect result_cull = Rect::MakeXYWH(0, 0, 10, 10);
90 
91  Canvas canvas(initial_cull);
92  canvas.ClipRect(rect_clip, Entity::ClipOperation::kDifference);
93 
94  ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
95  ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), result_cull);
96 }

References impeller::Canvas::ClipRect(), impeller::Canvas::GetCurrentLocalCullingBounds(), impeller::Entity::kDifference, and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST() [13/360]

impeller::testing::TEST ( AiksCanvasTest  ,
RectClipDiffAgainstVCoveredCullRect   
)

Definition at line 146 of file canvas_unittests.cc.

146  {
147  Rect initial_cull = Rect::MakeXYWH(0, 0, 10, 10);
148  Rect rect_clip = Rect::MakeXYWH(5, 0, 10, 10);
149  Rect result_cull = Rect::MakeXYWH(0, 0, 5, 10);
150 
151  Canvas canvas(initial_cull);
152  canvas.ClipRect(rect_clip, Entity::ClipOperation::kDifference);
153 
154  ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
155  ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), result_cull);
156 }

References impeller::Canvas::ClipRect(), impeller::Canvas::GetCurrentLocalCullingBounds(), impeller::Entity::kDifference, and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST() [14/360]

impeller::testing::TEST ( AiksCanvasTest  ,
RectClipDiffBelowCullRect   
)

Definition at line 110 of file canvas_unittests.cc.

110  {
111  Rect initial_cull = Rect::MakeXYWH(5, 5, 10, 10);
112  Rect rect_clip = Rect::MakeXYWH(0, 16, 20, 4);
113  Rect result_cull = Rect::MakeXYWH(5, 5, 10, 10);
114 
115  Canvas canvas(initial_cull);
116  canvas.ClipRect(rect_clip, Entity::ClipOperation::kDifference);
117 
118  ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
119  ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), result_cull);
120 }

References impeller::Canvas::ClipRect(), impeller::Canvas::GetCurrentLocalCullingBounds(), impeller::Entity::kDifference, and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST() [15/360]

impeller::testing::TEST ( AiksCanvasTest  ,
RectClipDiffLeftOfCullRect   
)

Definition at line 122 of file canvas_unittests.cc.

122  {
123  Rect initial_cull = Rect::MakeXYWH(5, 5, 10, 10);
124  Rect rect_clip = Rect::MakeXYWH(0, 0, 4, 20);
125  Rect result_cull = Rect::MakeXYWH(5, 5, 10, 10);
126 
127  Canvas canvas(initial_cull);
128  canvas.ClipRect(rect_clip, Entity::ClipOperation::kDifference);
129 
130  ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
131  ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), result_cull);
132 }

References impeller::Canvas::ClipRect(), impeller::Canvas::GetCurrentLocalCullingBounds(), impeller::Entity::kDifference, and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST() [16/360]

impeller::testing::TEST ( AiksCanvasTest  ,
RectClipDiffRightOfCullRect   
)

Definition at line 134 of file canvas_unittests.cc.

134  {
135  Rect initial_cull = Rect::MakeXYWH(5, 5, 10, 10);
136  Rect rect_clip = Rect::MakeXYWH(16, 0, 4, 20);
137  Rect result_cull = Rect::MakeXYWH(5, 5, 10, 10);
138 
139  Canvas canvas(initial_cull);
140  canvas.ClipRect(rect_clip, Entity::ClipOperation::kDifference);
141 
142  ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
143  ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), result_cull);
144 }

References impeller::Canvas::ClipRect(), impeller::Canvas::GetCurrentLocalCullingBounds(), impeller::Entity::kDifference, and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST() [17/360]

impeller::testing::TEST ( AiksCanvasTest  ,
RectClipIntersectAgainstCullRect   
)

Definition at line 74 of file canvas_unittests.cc.

74  {
75  Rect initial_cull = Rect::MakeXYWH(0, 0, 10, 10);
76  Rect rect_clip = Rect::MakeXYWH(5, 5, 10, 10);
77  Rect result_cull = Rect::MakeXYWH(5, 5, 5, 5);
78 
79  Canvas canvas(initial_cull);
80  canvas.ClipRect(rect_clip, Entity::ClipOperation::kIntersect);
81 
82  ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
83  ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), result_cull);
84 }

References impeller::Canvas::ClipRect(), impeller::Canvas::GetCurrentLocalCullingBounds(), impeller::Entity::kIntersect, and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST() [18/360]

impeller::testing::TEST ( AiksCanvasTest  ,
RectClipIntersectAgainstEmptyCullRect   
)

Definition at line 55 of file canvas_unittests.cc.

55  {
56  Rect rect_clip = Rect::MakeXYWH(5, 5, 10, 10);
57 
58  Canvas canvas;
59  canvas.ClipRect(rect_clip, Entity::ClipOperation::kIntersect);
60 
61  ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
62  ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), rect_clip);
63 }

References impeller::Canvas::ClipRect(), impeller::Canvas::GetCurrentLocalCullingBounds(), impeller::Entity::kIntersect, and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST() [19/360]

impeller::testing::TEST ( AiksCanvasTest  ,
RRectClipDiffAgainstEmptyCullRect   
)

Definition at line 180 of file canvas_unittests.cc.

180  {
181  Rect rect_clip = Rect::MakeXYWH(5, 5, 10, 10);
182 
183  Canvas canvas;
184  canvas.ClipRRect(rect_clip, {1, 1}, Entity::ClipOperation::kDifference);
185 
186  ASSERT_FALSE(canvas.GetCurrentLocalCullingBounds().has_value());
187 }

References impeller::Canvas::ClipRRect(), impeller::Canvas::GetCurrentLocalCullingBounds(), impeller::Entity::kDifference, and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST() [20/360]

impeller::testing::TEST ( AiksCanvasTest  ,
RRectClipDiffAgainstHFullyCoveredCullRect   
)

Definition at line 249 of file canvas_unittests.cc.

249  {
250  Rect initial_cull = Rect::MakeXYWH(0, 0, 10, 10);
251  Rect rect_clip = Rect::MakeXYWH(-2, 5, 14, 10);
252  Rect result_cull = Rect::MakeXYWH(0, 0, 10, 5);
253 
254  Canvas canvas(initial_cull);
255  canvas.ClipRRect(rect_clip, {1, 1}, Entity::ClipOperation::kDifference);
256 
257  ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
258  ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), result_cull);
259 }

References impeller::Canvas::ClipRRect(), impeller::Canvas::GetCurrentLocalCullingBounds(), impeller::Entity::kDifference, and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST() [21/360]

impeller::testing::TEST ( AiksCanvasTest  ,
RRectClipDiffAgainstHPartiallyCoveredCullRect   
)

Definition at line 237 of file canvas_unittests.cc.

237  {
238  Rect initial_cull = Rect::MakeXYWH(0, 0, 10, 10);
239  Rect rect_clip = Rect::MakeXYWH(0, 5, 10, 10);
240  Rect result_cull = Rect::MakeXYWH(0, 0, 10, 6);
241 
242  Canvas canvas(initial_cull);
243  canvas.ClipRRect(rect_clip, {1, 1}, Entity::ClipOperation::kDifference);
244 
245  ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
246  ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), result_cull);
247 }

References impeller::Canvas::ClipRRect(), impeller::Canvas::GetCurrentLocalCullingBounds(), impeller::Entity::kDifference, and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST() [22/360]

impeller::testing::TEST ( AiksCanvasTest  ,
RRectClipDiffAgainstNonCoveredCullRect   
)

Definition at line 201 of file canvas_unittests.cc.

201  {
202  Rect initial_cull = Rect::MakeXYWH(0, 0, 10, 10);
203  Rect rect_clip = Rect::MakeXYWH(5, 5, 10, 10);
204  Rect result_cull = Rect::MakeXYWH(0, 0, 10, 10);
205 
206  Canvas canvas(initial_cull);
207  canvas.ClipRRect(rect_clip, {1, 1}, Entity::ClipOperation::kDifference);
208 
209  ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
210  ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), result_cull);
211 }

References impeller::Canvas::ClipRRect(), impeller::Canvas::GetCurrentLocalCullingBounds(), impeller::Entity::kDifference, and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST() [23/360]

impeller::testing::TEST ( AiksCanvasTest  ,
RRectClipDiffAgainstVFullyCoveredCullRect   
)

Definition at line 225 of file canvas_unittests.cc.

225  {
226  Rect initial_cull = Rect::MakeXYWH(0, 0, 10, 10);
227  Rect rect_clip = Rect::MakeXYWH(5, -2, 10, 14);
228  Rect result_cull = Rect::MakeXYWH(0, 0, 5, 10);
229 
230  Canvas canvas(initial_cull);
231  canvas.ClipRRect(rect_clip, {1, 1}, Entity::ClipOperation::kDifference);
232 
233  ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
234  ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), result_cull);
235 }

References impeller::Canvas::ClipRRect(), impeller::Canvas::GetCurrentLocalCullingBounds(), impeller::Entity::kDifference, and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST() [24/360]

impeller::testing::TEST ( AiksCanvasTest  ,
RRectClipDiffAgainstVPartiallyCoveredCullRect   
)

Definition at line 213 of file canvas_unittests.cc.

213  {
214  Rect initial_cull = Rect::MakeXYWH(0, 0, 10, 10);
215  Rect rect_clip = Rect::MakeXYWH(5, 0, 10, 10);
216  Rect result_cull = Rect::MakeXYWH(0, 0, 6, 10);
217 
218  Canvas canvas(initial_cull);
219  canvas.ClipRRect(rect_clip, {1, 1}, Entity::ClipOperation::kDifference);
220 
221  ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
222  ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), result_cull);
223 }

References impeller::Canvas::ClipRRect(), impeller::Canvas::GetCurrentLocalCullingBounds(), impeller::Entity::kDifference, and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST() [25/360]

impeller::testing::TEST ( AiksCanvasTest  ,
RRectClipIntersectAgainstCullRect   
)

Definition at line 189 of file canvas_unittests.cc.

189  {
190  Rect initial_cull = Rect::MakeXYWH(0, 0, 10, 10);
191  Rect rect_clip = Rect::MakeXYWH(5, 5, 10, 10);
192  Rect result_cull = Rect::MakeXYWH(5, 5, 5, 5);
193 
194  Canvas canvas(initial_cull);
195  canvas.ClipRRect(rect_clip, {1, 1}, Entity::ClipOperation::kIntersect);
196 
197  ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
198  ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), result_cull);
199 }

References impeller::Canvas::ClipRRect(), impeller::Canvas::GetCurrentLocalCullingBounds(), impeller::Entity::kIntersect, and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST() [26/360]

impeller::testing::TEST ( AiksCanvasTest  ,
RRectClipIntersectAgainstEmptyCullRect   
)

Definition at line 170 of file canvas_unittests.cc.

170  {
171  Rect rect_clip = Rect::MakeXYWH(5, 5, 10, 10);
172 
173  Canvas canvas;
174  canvas.ClipRRect(rect_clip, {1, 1}, Entity::ClipOperation::kIntersect);
175 
176  ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
177  ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), rect_clip);
178 }

References impeller::Canvas::ClipRRect(), impeller::Canvas::GetCurrentLocalCullingBounds(), impeller::Entity::kIntersect, and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST() [27/360]

impeller::testing::TEST ( AiksCanvasTest  ,
ScaledCullRect   
)

Definition at line 44 of file canvas_unittests.cc.

44  {
45  Rect initial_cull = Rect::MakeXYWH(5, 5, 10, 10);
46  Rect scaled_cull = Rect::MakeXYWH(10, 10, 20, 20);
47 
48  Canvas canvas(initial_cull);
49  canvas.Scale(Vector2(0.5, 0.5));
50 
51  ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
52  ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), scaled_cull);
53 }

References impeller::Canvas::GetCurrentLocalCullingBounds(), impeller::TRect< Scalar >::MakeXYWH(), and impeller::Canvas::Scale().

◆ TEST() [28/360]

impeller::testing::TEST ( AiksCanvasTest  ,
TranslatedCullRect   
)

Definition at line 33 of file canvas_unittests.cc.

33  {
34  Rect initial_cull = Rect::MakeXYWH(5, 5, 10, 10);
35  Rect translated_cull = Rect::MakeXYWH(0, 0, 10, 10);
36 
37  Canvas canvas(initial_cull);
38  canvas.Translate(Vector3(5, 5, 0));
39 
40  ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
41  ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), translated_cull);
42 }

References impeller::Canvas::GetCurrentLocalCullingBounds(), impeller::TRect< Scalar >::MakeXYWH(), and impeller::Canvas::Translate().

◆ TEST() [29/360]

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 }

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

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

Definition at line 35 of file allocator_vk_unittests.cc.

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

References impeller::AllocatorVK::FindMemoryTypeIndex().

◆ TEST() [31/360]

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

Definition at line 50 of file allocator_vk_unittests.cc.

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

References impeller::AllocatorVK::FindMemoryTypeIndex().

◆ TEST() [32/360]

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

Definition at line 16 of file allocator_vk_unittests.cc.

16  {
17  EXPECT_EQ(AllocatorVK::ToVKImageUsageFlags(
18  PixelFormat::kR8G8B8A8UNormInt,
19  static_cast<TextureUsageMask>(TextureUsage::kRenderTarget),
20  StorageMode::kDeviceTransient,
21  /*supports_memoryless_textures=*/true),
22  vk::ImageUsageFlagBits::eInputAttachment |
23  vk::ImageUsageFlagBits::eColorAttachment |
24  vk::ImageUsageFlagBits::eTransientAttachment);
25 
26  EXPECT_EQ(AllocatorVK::ToVKImageUsageFlags(
27  PixelFormat::kD24UnormS8Uint,
28  static_cast<TextureUsageMask>(TextureUsage::kRenderTarget),
29  StorageMode::kDeviceTransient,
30  /*supports_memoryless_textures=*/true),
31  vk::ImageUsageFlagBits::eDepthStencilAttachment |
32  vk::ImageUsageFlagBits::eTransientAttachment);
33 }

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

◆ TEST() [33/360]

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

Definition at line 266 of file base_unittests.cc.

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

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

◆ TEST() [34/360]

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

Definition at line 257 of file base_unittests.cc.

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

◆ TEST() [35/360]

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

Definition at line 250 of file base_unittests.cc.

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

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

◆ TEST() [36/360]

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

Definition at line 31 of file capabilities_unittests.cc.

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

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

◆ TEST() [37/360]

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

Definition at line 49 of file capabilities_unittests.cc.

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

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

◆ TEST() [38/360]

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

Definition at line 59 of file capabilities_unittests.cc.

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

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

◆ TEST() [39/360]

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

Definition at line 40 of file capabilities_unittests.cc.

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

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

◆ TEST() [40/360]

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

Definition at line 195 of file context_vk_unittests.cc.

196  {
197  ScopedValidationDisable disable_validation;
198  const std::shared_ptr<ContextVK> context =
199  MockVulkanContextBuilder()
200  .SetPhysicalDeviceFormatPropertiesCallback(
201  [](VkPhysicalDevice physicalDevice, VkFormat format,
202  VkFormatProperties* pFormatProperties) {
203  if (format == VK_FORMAT_R8G8B8A8_UNORM) {
204  pFormatProperties->optimalTilingFeatures =
205  static_cast<VkFormatFeatureFlags>(
206  vk::FormatFeatureFlagBits::eColorAttachment);
207  }
208  // Ignore combined depth-stencil formats.
209  })
210  .Build();
211  ASSERT_EQ(context, nullptr);
212 }

◆ TEST() [41/360]

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

Definition at line 164 of file context_vk_unittests.cc.

164  {
165  const std::shared_ptr<ContextVK> context =
166  MockVulkanContextBuilder()
167  .SetPhysicalDeviceFormatPropertiesCallback(
168  [](VkPhysicalDevice physicalDevice, VkFormat format,
169  VkFormatProperties* pFormatProperties) {
170  if (format == VK_FORMAT_R8G8B8A8_UNORM) {
171  pFormatProperties->optimalTilingFeatures =
172  static_cast<VkFormatFeatureFlags>(
173  vk::FormatFeatureFlagBits::eColorAttachment);
174  } else if (format == VK_FORMAT_D32_SFLOAT_S8_UINT) {
175  pFormatProperties->optimalTilingFeatures =
176  static_cast<VkFormatFeatureFlags>(
177  vk::FormatFeatureFlagBits::eDepthStencilAttachment);
178  }
179  // Ignore just the stencil format.
180  })
181  .Build();
182  ASSERT_NE(context, nullptr);
183  const CapabilitiesVK* capabilites_vk =
184  reinterpret_cast<const CapabilitiesVK*>(context->GetCapabilities().get());
185  ASSERT_EQ(capabilites_vk->GetDefaultDepthStencilFormat(),
186  PixelFormat::kD32FloatS8UInt);
187  ASSERT_EQ(capabilites_vk->GetDefaultStencilFormat(),
188  PixelFormat::kD32FloatS8UInt);
189 }

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

◆ TEST() [42/360]

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

Definition at line 42 of file command_encoder_vk_unittests.cc.

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

References impeller::CommandBuffer::kCompleted.

◆ TEST() [43/360]

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

Definition at line 16 of file command_encoder_vk_unittests.cc.

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

References impeller::CommandEncoderFactoryVK::Create().

◆ TEST() [44/360]

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

Definition at line 115 of file command_pool_vk_unittests.cc.

115  {
116  auto const context = MockVulkanContextBuilder().Build();
117 
118  {
119  // Fetch a pool (which will be created).
120  auto const recycler = context->GetCommandPoolRecycler();
121  auto pool = recycler->Get();
122 
123  auto buffer = pool->CreateCommandBuffer();
124  pool->CollectCommandBuffer(std::move(buffer));
125 
126  // This normally is called at the end of a frame.
127  recycler->Dispose();
128  }
129 
130  // Wait for the pool to be reclaimed.
131  for (auto i = 0u; i < 2u; i++) {
132  auto waiter = fml::AutoResetWaitableEvent();
133  auto rattle = DeathRattle([&waiter]() { waiter.Signal(); });
134  {
135  UniqueResourceVKT<DeathRattle> resource(context->GetResourceManager(),
136  std::move(rattle));
137  }
138  waiter.Wait();
139  }
140 
141  {
142  // Create a second pool and command buffer, which should reused the existing
143  // pool and cmd buffer.
144  auto const recycler = context->GetCommandPoolRecycler();
145  auto pool = recycler->Get();
146 
147  auto buffer = pool->CreateCommandBuffer();
148  pool->CollectCommandBuffer(std::move(buffer));
149 
150  // This normally is called at the end of a frame.
151  recycler->Dispose();
152  }
153 
154  // Now check that we only ever created one pool and one command buffer.
155  auto const called = GetMockVulkanFunctions(context->GetDevice());
156  EXPECT_EQ(std::count(called->begin(), called->end(), "vkCreateCommandPool"),
157  1u);
158  EXPECT_EQ(
159  std::count(called->begin(), called->end(), "vkAllocateCommandBuffers"),
160  1u);
161 
162  context->Shutdown();
163 }

◆ TEST() [45/360]

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

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

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

Definition at line 76 of file command_pool_vk_unittests.cc.

76  {
77  auto const context = MockVulkanContextBuilder().Build();
78 
79  {
80  // Fetch a pool (which will be created).
81  auto const recycler = context->GetCommandPoolRecycler();
82  auto const pool = recycler->Get();
83 
84  // This normally is called at the end of a frame.
85  recycler->Dispose();
86  }
87 
88  // Add something to the resource manager and have it notify us when it's
89  // destroyed. That should give us a non-flaky signal that the pool has been
90  // reclaimed as well.
91  auto waiter = fml::AutoResetWaitableEvent();
92  auto rattle = DeathRattle([&waiter]() { waiter.Signal(); });
93  {
94  UniqueResourceVKT<DeathRattle> resource(context->GetResourceManager(),
95  std::move(rattle));
96  }
97  waiter.Wait();
98 
99  // On another thread explicitly, request a new pool.
100  std::thread thread([&]() {
101  auto const pool = context->GetCommandPoolRecycler()->Get();
102  EXPECT_NE(pool.get(), nullptr);
103  });
104 
105  thread.join();
106 
107  // Now check that we only ever created one pool.
108  auto const called = GetMockVulkanFunctions(context->GetDevice());
109  EXPECT_EQ(std::count(called->begin(), called->end(), "vkCreateCommandPool"),
110  1u);
111 
112  context->Shutdown();
113 }

◆ TEST() [48/360]

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

Definition at line 205 of file base_unittests.cc.

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

References impeller::ConditionVariable::Wait().

◆ TEST() [49/360]

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

Definition at line 160 of file base_unittests.cc.

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

References impeller::ConditionVariable::WaitFor().

◆ TEST() [50/360]

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

Definition at line 122 of file base_unittests.cc.

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

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

◆ TEST() [51/360]

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

Definition at line 143 of file base_unittests.cc.

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

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

◆ TEST() [52/360]

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

Definition at line 99 of file base_unittests.cc.

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

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

◆ TEST() [53/360]

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

Definition at line 132 of file context_vk_unittests.cc.

132  {
133  // The mocked methods don't report the presence of a validation layer but we
134  // explicitly ask for validation. Context creation should continue anyway.
135  auto context = MockVulkanContextBuilder()
136  .SetSettingsCallback([](auto& settings) {
137  settings.enable_validation = true;
138  })
139  .Build();
140  ASSERT_NE(context, nullptr);
141  const CapabilitiesVK* capabilites_vk =
142  reinterpret_cast<const CapabilitiesVK*>(context->GetCapabilities().get());
143  ASSERT_FALSE(capabilites_vk->AreValidationsEnabled());
144 }

References impeller::CapabilitiesVK::AreValidationsEnabled().

◆ TEST() [54/360]

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

Definition at line 146 of file context_vk_unittests.cc.

146  {
147  auto context =
148  MockVulkanContextBuilder()
149  .SetSettingsCallback(
150  [](auto& settings) { settings.enable_validation = true; })
151  .SetInstanceExtensions(
152  {"VK_KHR_surface", "VK_MVK_macos_surface", "VK_EXT_debug_utils"})
153  .SetInstanceLayers({"VK_LAYER_KHRONOS_validation"})
154  .Build();
155  ASSERT_NE(context, nullptr);
156  const CapabilitiesVK* capabilites_vk =
157  reinterpret_cast<const CapabilitiesVK*>(context->GetCapabilities().get());
158  ASSERT_TRUE(capabilites_vk->AreValidationsEnabled());
159 }

References impeller::CapabilitiesVK::AreValidationsEnabled().

◆ TEST() [55/360]

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

Definition at line 16 of file context_vk_unittests.cc.

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

References impeller::ContextVK::ChooseThreadCountForWorkers().

◆ TEST() [56/360]

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

Definition at line 75 of file context_vk_unittests.cc.

75  {
76  std::shared_ptr<Pipeline<PipelineDescriptor>> pipeline;
77  std::shared_ptr<std::vector<std::string>> functions;
78  {
79  std::shared_ptr<ContextVK> context = MockVulkanContextBuilder().Build();
80  PipelineDescriptor pipeline_desc;
81  pipeline_desc.SetVertexDescriptor(std::make_shared<VertexDescriptor>());
82  PipelineFuture<PipelineDescriptor> pipeline_future =
83  context->GetPipelineLibrary()->GetPipeline(pipeline_desc);
84  pipeline = pipeline_future.Get();
85  ASSERT_TRUE(pipeline);
86  functions = GetMockVulkanFunctions(context->GetDevice());
87  ASSERT_TRUE(std::find(functions->begin(), functions->end(),
88  "vkCreateGraphicsPipelines") != functions->end());
89  }
90  ASSERT_TRUE(std::find(functions->begin(), functions->end(),
91  "vkDestroyDevice") != functions->end());
92 }

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

◆ TEST() [57/360]

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

Definition at line 116 of file context_vk_unittests.cc.

116  {
117  std::shared_ptr<PipelineLibrary> pipeline_library;
118  std::shared_ptr<std::vector<std::string>> functions;
119  {
120  std::shared_ptr<ContextVK> context = MockVulkanContextBuilder().Build();
121  PipelineDescriptor pipeline_desc;
122  pipeline_desc.SetVertexDescriptor(std::make_shared<VertexDescriptor>());
123  pipeline_library = context->GetPipelineLibrary();
124  functions = GetMockVulkanFunctions(context->GetDevice());
125  ASSERT_TRUE(std::find(functions->begin(), functions->end(),
126  "vkCreatePipelineCache") != functions->end());
127  }
128  ASSERT_TRUE(std::find(functions->begin(), functions->end(),
129  "vkDestroyDevice") != functions->end());
130 }

References impeller::PipelineDescriptor::SetVertexDescriptor().

◆ TEST() [58/360]

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

Definition at line 29 of file context_vk_unittests.cc.

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

◆ TEST() [59/360]

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

Definition at line 44 of file context_vk_unittests.cc.

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

◆ TEST() [60/360]

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

Definition at line 94 of file context_vk_unittests.cc.

94  {
95  std::shared_ptr<const ShaderFunction> shader_function;
96  std::shared_ptr<std::vector<std::string>> functions;
97  {
98  std::shared_ptr<ContextVK> context = MockVulkanContextBuilder().Build();
99  PipelineDescriptor pipeline_desc;
100  pipeline_desc.SetVertexDescriptor(std::make_shared<VertexDescriptor>());
101  std::vector<uint8_t> data = {0x03, 0x02, 0x23, 0x07};
102  context->GetShaderLibrary()->RegisterFunction(
103  "foobar_fragment_main", ShaderStage::kFragment,
104  std::make_shared<fml::DataMapping>(data), [](bool) {});
105  shader_function = context->GetShaderLibrary()->GetFunction(
106  "foobar_fragment_main", ShaderStage::kFragment);
107  ASSERT_TRUE(shader_function);
108  functions = GetMockVulkanFunctions(context->GetDevice());
109  ASSERT_TRUE(std::find(functions->begin(), functions->end(),
110  "vkCreateShaderModule") != functions->end());
111  }
112  ASSERT_TRUE(std::find(functions->begin(), functions->end(),
113  "vkDestroyDevice") != functions->end());
114 }

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

◆ TEST() [61/360]

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

Definition at line 225 of file context_vk_unittests.cc.

225  {
226  EXPECT_DEATH(const std::shared_ptr<ContextVK> context =
227  MockVulkanContextBuilder()
228  .SetSettingsCallback([](ContextVK::Settings& settings) {
229  settings.enable_validation = true;
230  settings.fatal_missing_validations = true;
231  })
232  .Build(),
233  "");
234 }

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

◆ TEST() [62/360]

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

Definition at line 236 of file context_vk_unittests.cc.

236  {
237  std::shared_ptr<ContextVK> context = MockVulkanContextBuilder().Build();
238 
239  const CapabilitiesVK* capabilites_vk =
240  reinterpret_cast<const CapabilitiesVK*>(context->GetCapabilities().get());
241  ASSERT_NE(capabilites_vk->GetDefaultColorFormat(), PixelFormat::kUnknown);
242 }

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

◆ TEST() [63/360]

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

Definition at line 214 of file context_vk_unittests.cc.

214  {
215  const std::shared_ptr<ContextVK> context = MockVulkanContextBuilder().Build();
216 
217  context->SetOffscreenFormat(PixelFormat::kR8G8B8A8UNormInt);
218  context->InitializeCommonlyUsedShadersIfNeeded();
219 
220  auto functions = GetMockVulkanFunctions(context->GetDevice());
221  ASSERT_TRUE(std::find(functions->begin(), functions->end(),
222  "vkCreateRenderPass") != functions->end());
223 }

References impeller::kR8G8B8A8UNormInt.

◆ TEST() [64/360]

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

Definition at line 15 of file descriptor_pool_vk_unittests.cc.

15  {
16  auto const context = MockVulkanContextBuilder().Build();
17 
18  auto const pool1 = context->GetDescriptorPoolRecycler()->Get();
19  auto const pool2 = context->GetDescriptorPoolRecycler()->Get();
20 
21  // The two descriptor pools should be different.
22  EXPECT_NE(pool1.get(), pool2.get());
23 
24  context->Shutdown();
25 }

◆ TEST() [65/360]

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

Definition at line 65 of file descriptor_pool_vk_unittests.cc.

65  {
66  auto const context = MockVulkanContextBuilder().Build();
67 
68  // Create 33 pools
69  {
70  std::vector<std::unique_ptr<DescriptorPoolVK>> pools;
71  for (auto i = 0u; i < 33; i++) {
72  auto pool = std::make_unique<DescriptorPoolVK>(context);
73  pool->AllocateDescriptorSets({}, *context);
74  pools.push_back(std::move(pool));
75  }
76  }
77 
78  // See note above.
79  for (auto i = 0u; i < 2; i++) {
80  auto waiter = fml::AutoResetWaitableEvent();
81  auto rattle = fml::ScopedCleanupClosure([&waiter]() { waiter.Signal(); });
82  {
83  UniqueResourceVKT<fml::ScopedCleanupClosure> resource(
84  context->GetResourceManager(), std::move(rattle));
85  }
86  waiter.Wait();
87  }
88 
89  auto const called = GetMockVulkanFunctions(context->GetDevice());
90  EXPECT_EQ(
91  std::count(called->begin(), called->end(), "vkCreateDescriptorPool"),
92  33u);
93  EXPECT_EQ(std::count(called->begin(), called->end(), "vkResetDescriptorPool"),
94  33u);
95 
96  // Now create 33 more descriptor pools and observe that only one more is
97  // allocated.
98  {
99  std::vector<std::unique_ptr<DescriptorPoolVK>> pools;
100  for (auto i = 0u; i < 33; i++) {
101  auto pool = std::make_unique<DescriptorPoolVK>(context);
102  pool->AllocateDescriptorSets({}, *context);
103  pools.push_back(std::move(pool));
104  }
105  }
106 
107  for (auto i = 0u; i < 2; i++) {
108  auto waiter = fml::AutoResetWaitableEvent();
109  auto rattle = fml::ScopedCleanupClosure([&waiter]() { waiter.Signal(); });
110  {
111  UniqueResourceVKT<fml::ScopedCleanupClosure> resource(
112  context->GetResourceManager(), std::move(rattle));
113  }
114  waiter.Wait();
115  }
116 
117  auto const called_twice = GetMockVulkanFunctions(context->GetDevice());
118  // 32 of the descriptor pools were recycled, so only one more is created.
119  EXPECT_EQ(
120  std::count(called->begin(), called->end(), "vkCreateDescriptorPool"),
121  34u);
122 
123  context->Shutdown();
124 }

◆ TEST() [66/360]

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

Definition at line 27 of file descriptor_pool_vk_unittests.cc.

27  {
28  auto const context = MockVulkanContextBuilder().Build();
29 
30  {
31  // Fetch a pool (which will be created).
32  auto pool = DescriptorPoolVK(context);
33  pool.AllocateDescriptorSets({}, *context);
34  }
35 
36  // There is a chance that the first death rattle item below is destroyed in
37  // the same reclaim cycle as the pool allocation above. These items are placed
38  // into a std::vector and free'd, which may free in reverse order. That would
39  // imply that the death rattle and subsequent waitable event fires before the
40  // pool is reset. To work around this, we can either manually remove items
41  // from the vector or use two death rattles.
42  for (auto i = 0u; i < 2; i++) {
43  // Add something to the resource manager and have it notify us when it's
44  // destroyed. That should give us a non-flaky signal that the pool has been
45  // reclaimed as well.
46  auto waiter = fml::AutoResetWaitableEvent();
47  auto rattle = fml::ScopedCleanupClosure([&waiter]() { waiter.Signal(); });
48  {
49  UniqueResourceVKT<fml::ScopedCleanupClosure> resource(
50  context->GetResourceManager(), std::move(rattle));
51  }
52  waiter.Wait();
53  }
54 
55  auto const pool = context->GetDescriptorPoolRecycler()->Get();
56 
57  // Now check that we only ever created one pool.
58  auto const called = GetMockVulkanFunctions(context->GetDevice());
59  EXPECT_EQ(
60  std::count(called->begin(), called->end(), "vkCreateDescriptorPool"), 1u);
61 
62  context->Shutdown();
63 }

◆ TEST() [67/360]

impeller::testing::TEST ( DisplayListTest  ,
CircleBoundsComputation   
)

Definition at line 1584 of file dl_unittests.cc.

1584  {
1585  SkPath path = SkPath().addCircle(0, 0, 5);
1586 
1587  flutter::DlPaint paint;
1588  flutter::DisplayListBuilder builder;
1589 
1590  builder.DrawPath(path, paint);
1591  auto display_list = builder.Build();
1592 
1593  DlDispatcher dispatcher;
1594  display_list->Dispatch(dispatcher);
1595  auto picture = dispatcher.EndRecordingAsPicture();
1596 
1597  std::optional<Rect> coverage =
1598  GetCoverageOfFirstEntity<SolidColorContents>(picture);
1599 
1600  ASSERT_TRUE(coverage.has_value());
1601  ASSERT_EQ(coverage.value_or(Rect::MakeMaximum()),
1602  Rect::MakeLTRB(-5, -5, 5, 5));
1603 }

References impeller::DlDispatcherBase::EndRecordingAsPicture(), impeller::TRect< Scalar >::MakeLTRB(), impeller::TRect< Scalar >::MakeMaximum(), and paint.

◆ TEST() [68/360]

impeller::testing::TEST ( DisplayListTest  ,
RRectBoundsComputation   
)

Definition at line 1561 of file dl_unittests.cc.

1561  {
1562  SkRRect rrect = SkRRect::MakeRectXY(SkRect::MakeLTRB(0, 0, 100, 100), 4, 4);
1563  SkPath path = SkPath().addRRect(rrect);
1564 
1565  flutter::DlPaint paint;
1566  flutter::DisplayListBuilder builder;
1567 
1568  builder.DrawPath(path, paint);
1569  auto display_list = builder.Build();
1570 
1571  DlDispatcher dispatcher;
1572  display_list->Dispatch(dispatcher);
1573  auto picture = dispatcher.EndRecordingAsPicture();
1574 
1575  std::optional<Rect> coverage =
1576  GetCoverageOfFirstEntity<SolidColorContents>(picture);
1577 
1578  // Validate that the RRect coverage is _exactly_ the same as the input rect.
1579  ASSERT_TRUE(coverage.has_value());
1580  ASSERT_EQ(coverage.value_or(Rect::MakeMaximum()),
1581  Rect::MakeLTRB(0, 0, 100, 100));
1582 }

References impeller::DlDispatcherBase::EndRecordingAsPicture(), impeller::TRect< Scalar >::MakeLTRB(), impeller::TRect< Scalar >::MakeMaximum(), and paint.

◆ TEST() [69/360]

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

Definition at line 139 of file geometry_unittests.cc.

139  {
140  Entity entity;
141  entity.SetTransform(Matrix::MakeScale(Vector2{3.0, 3.0}));
142  EXPECT_EQ(Geometry::MakeStrokePath({}, 0.5)->ComputeAlphaCoverage(entity), 1);
143  EXPECT_EQ(Geometry::MakeStrokePath({}, 0.1)->ComputeAlphaCoverage(entity), 1);
144  EXPECT_EQ(Geometry::MakeStrokePath({}, 0.05)->ComputeAlphaCoverage(entity),
145  1);
146  EXPECT_NEAR(Geometry::MakeStrokePath({}, 0.01)->ComputeAlphaCoverage(entity),
147  0.6, 0.1);
148  EXPECT_NEAR(
149  Geometry::MakeStrokePath({}, 0.0000005)->ComputeAlphaCoverage(entity),
150  1e-05, 0.001);
151  EXPECT_EQ(Geometry::MakeStrokePath({}, 0)->ComputeAlphaCoverage(entity), 1);
152  EXPECT_EQ(Geometry::MakeStrokePath({}, 40)->ComputeAlphaCoverage(entity), 1);
153 }

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

◆ TEST() [70/360]

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

Definition at line 78 of file geometry_unittests.cc.

78  {
79  auto path = PathBuilder{}.AddRect(Rect::MakeLTRB(0, 0, 100, 100)).TakePath();
80  auto geometry = Geometry::MakeFillPath(
81  path, /* inner rect */ Rect::MakeLTRB(0, 0, 100, 100));
82  ASSERT_TRUE(geometry->CoversArea({}, Rect::MakeLTRB(0, 0, 100, 100)));
83  ASSERT_FALSE(geometry->CoversArea({}, Rect::MakeLTRB(-1, 0, 100, 100)));
84  ASSERT_TRUE(geometry->CoversArea({}, Rect::MakeLTRB(1, 1, 100, 100)));
85  ASSERT_TRUE(geometry->CoversArea({}, Rect()));
86 }

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

◆ TEST() [71/360]

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

Definition at line 88 of file geometry_unittests.cc.

88  {
89  auto path = PathBuilder{}.AddRect(Rect::MakeLTRB(0, 0, 100, 100)).TakePath();
90  auto geometry = Geometry::MakeFillPath(path);
91  ASSERT_FALSE(geometry->CoversArea({}, Rect::MakeLTRB(0, 0, 100, 100)));
92  ASSERT_FALSE(geometry->CoversArea({}, Rect::MakeLTRB(-1, 0, 100, 100)));
93  ASSERT_FALSE(geometry->CoversArea({}, Rect::MakeLTRB(1, 1, 100, 100)));
94  ASSERT_FALSE(geometry->CoversArea({}, Rect()));
95 }

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

◆ TEST() [72/360]

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

Definition at line 132 of file geometry_unittests.cc.

132  {
133  GeometryResult result;
134  EXPECT_EQ(result.type, PrimitiveType::kTriangleStrip);
135  EXPECT_EQ(result.transform, Matrix());
136  EXPECT_EQ(result.mode, GeometryResult::Mode::kNormal);
137 }

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

◆ TEST() [73/360]

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

Definition at line 97 of file geometry_unittests.cc.

97  {
98  {
99  auto geometry = Geometry::MakeLine({10, 10}, {20, 10}, 2, Cap::kButt);
100  EXPECT_EQ(geometry->GetCoverage({}), Rect::MakeLTRB(10, 9, 20, 11));
101  EXPECT_TRUE(geometry->CoversArea({}, Rect::MakeLTRB(10, 9, 20, 11)));
102  }
103 
104  {
105  auto geometry = Geometry::MakeLine({10, 10}, {20, 10}, 2, Cap::kSquare);
106  EXPECT_EQ(geometry->GetCoverage({}), Rect::MakeLTRB(9, 9, 21, 11));
107  EXPECT_TRUE(geometry->CoversArea({}, Rect::MakeLTRB(9, 9, 21, 11)));
108  }
109 
110  {
111  auto geometry = Geometry::MakeLine({10, 10}, {10, 20}, 2, Cap::kButt);
112  EXPECT_EQ(geometry->GetCoverage({}), Rect::MakeLTRB(9, 10, 11, 20));
113  EXPECT_TRUE(geometry->CoversArea({}, Rect::MakeLTRB(9, 10, 11, 20)));
114  }
115 
116  {
117  auto geometry = Geometry::MakeLine({10, 10}, {10, 20}, 2, Cap::kSquare);
118  EXPECT_EQ(geometry->GetCoverage({}), Rect::MakeLTRB(9, 9, 11, 21));
119  EXPECT_TRUE(geometry->CoversArea({}, Rect::MakeLTRB(9, 9, 11, 21)));
120  }
121 }

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

◆ TEST() [74/360]

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

Definition at line 70 of file geometry_unittests.cc.

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

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

◆ TEST() [75/360]

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

Definition at line 123 of file geometry_unittests.cc.

123  {
124  auto geometry =
125  Geometry::MakeRoundRect(Rect::MakeLTRB(0, 0, 100, 100), Size(20, 20));
126  EXPECT_FALSE(geometry->CoversArea({}, Rect::MakeLTRB(15, 15, 85, 85)));
127  EXPECT_TRUE(geometry->CoversArea({}, Rect::MakeLTRB(20, 20, 80, 80)));
128  EXPECT_TRUE(geometry->CoversArea({}, Rect::MakeLTRB(30, 1, 70, 99)));
129  EXPECT_TRUE(geometry->CoversArea({}, Rect::MakeLTRB(1, 30, 99, 70)));
130 }

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

◆ TEST() [76/360]

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

Definition at line 92 of file entity_pass_unittests.cc.

92  {
93  EntityPassClipStack recorder =
94  EntityPassClipStack(Rect::MakeLTRB(0, 0, 100, 100));
95 
96  ASSERT_EQ(recorder.GetClipCoverageLayers().size(), 1u);
97 
98  // Push a clip.
99  Entity entity;
100  EntityPassClipStack::ClipStateResult result = recorder.ApplyClipState(
101  Contents::ClipCoverage{
102  .type = Contents::ClipCoverage::Type::kAppend,
103  .coverage = Rect::MakeLTRB(50, 50, 55, 55),
104  },
105  entity, 0, Point(0, 0));
106  EXPECT_TRUE(result.should_render);
107  EXPECT_TRUE(result.clip_did_change);
108 
109  ASSERT_EQ(recorder.GetClipCoverageLayers().size(), 2u);
110  EXPECT_EQ(recorder.GetClipCoverageLayers()[1].coverage,
111  Rect::MakeLTRB(50, 50, 55, 55));
112  EXPECT_EQ(recorder.GetClipCoverageLayers()[1].clip_height, 1u);
113  EXPECT_EQ(recorder.GetReplayEntities().size(), 1u);
114 
115  // Restore the clip.
116  auto restore_clip = std::make_shared<ClipRestoreContents>();
117  restore_clip->SetRestoreHeight(0);
118  entity.SetContents(std::move(restore_clip));
119  recorder.ApplyClipState(
120  Contents::ClipCoverage{
121  .type = Contents::ClipCoverage::Type::kRestore,
122  .coverage = Rect::MakeLTRB(50, 50, 55, 55),
123  },
124  entity, 0, Point(0, 0));
125 
126  ASSERT_EQ(recorder.GetClipCoverageLayers().size(), 1u);
127  EXPECT_EQ(recorder.GetClipCoverageLayers()[0].coverage,
128  Rect::MakeSize(Size::MakeWH(100, 100)));
129  EXPECT_EQ(recorder.GetClipCoverageLayers()[0].clip_height, 0u);
130  EXPECT_EQ(recorder.GetReplayEntities().size(), 0u);
131 }

References impeller::EntityPassClipStack::ApplyClipState(), impeller::EntityPassClipStack::ClipStateResult::clip_did_change, impeller::EntityPassClipStack::GetClipCoverageLayers(), impeller::EntityPassClipStack::GetReplayEntities(), impeller::Contents::ClipCoverage::kAppend, impeller::Contents::ClipCoverage::kRestore, impeller::TRect< Scalar >::MakeLTRB(), impeller::TRect< Scalar >::MakeSize(), impeller::TSize< Scalar >::MakeWH(), impeller::Entity::SetContents(), impeller::EntityPassClipStack::ClipStateResult::should_render, and impeller::Contents::ClipCoverage::type.

◆ TEST() [77/360]

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

Definition at line 69 of file entity_pass_unittests.cc.

69  {
70  EntityPassClipStack recorder =
71  EntityPassClipStack(Rect::MakeLTRB(0, 0, 100, 100));
72 
73  EXPECT_EQ(recorder.GetClipCoverageLayers()[0].coverage,
74  Rect::MakeSize(Size::MakeWH(100, 100)));
75  EXPECT_EQ(recorder.GetClipCoverageLayers()[0].clip_height, 0u);
76 
77  Entity entity;
78  EntityPassClipStack::ClipStateResult result = recorder.ApplyClipState(
79  Contents::ClipCoverage{
80  .type = Contents::ClipCoverage::Type::kNoChange,
81  .coverage = std::nullopt,
82  },
83  entity, 0, Point(0, 0));
84  EXPECT_TRUE(result.should_render);
85  EXPECT_FALSE(result.clip_did_change);
86 
87  EXPECT_EQ(recorder.GetClipCoverageLayers()[0].coverage,
88  Rect::MakeSize(Size::MakeWH(100, 100)));
89  EXPECT_EQ(recorder.GetClipCoverageLayers()[0].clip_height, 0u);
90 }

References impeller::EntityPassClipStack::ApplyClipState(), impeller::EntityPassClipStack::ClipStateResult::clip_did_change, impeller::EntityPassClipStack::GetClipCoverageLayers(), impeller::Contents::ClipCoverage::kNoChange, impeller::TRect< Scalar >::MakeLTRB(), impeller::TRect< Scalar >::MakeSize(), impeller::TSize< Scalar >::MakeWH(), impeller::EntityPassClipStack::ClipStateResult::should_render, and impeller::Contents::ClipCoverage::type.

◆ TEST() [78/360]

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

Definition at line 57 of file entity_pass_unittests.cc.

57  {
58  EntityPassClipStack recorder =
59  EntityPassClipStack(Rect::MakeLTRB(0, 0, 100, 100));
60 
61  EXPECT_TRUE(recorder.GetReplayEntities().empty());
62 
63  Entity entity;
64  recorder.RecordEntity(entity, Contents::ClipCoverage::Type::kNoChange,
65  Rect());
66  EXPECT_TRUE(recorder.GetReplayEntities().empty());
67 }

References impeller::EntityPassClipStack::GetReplayEntities(), impeller::Contents::ClipCoverage::kNoChange, impeller::TRect< Scalar >::MakeLTRB(), and impeller::EntityPassClipStack::RecordEntity().

◆ TEST() [79/360]

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

Definition at line 46 of file entity_pass_unittests.cc.

46  {
47  EntityPassClipStack recorder =
48  EntityPassClipStack(Rect::MakeLTRB(0, 0, 100, 100));
49 
50  EXPECT_TRUE(recorder.GetReplayEntities().empty());
51 
52  Entity entity;
53  recorder.RecordEntity(entity, Contents::ClipCoverage::Type::kRestore, Rect());
54  EXPECT_TRUE(recorder.GetReplayEntities().empty());
55 }

References impeller::EntityPassClipStack::GetReplayEntities(), impeller::Contents::ClipCoverage::kRestore, impeller::TRect< Scalar >::MakeLTRB(), and impeller::EntityPassClipStack::RecordEntity().

◆ TEST() [80/360]

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

Definition at line 16 of file entity_pass_unittests.cc.

16  {
17  EntityPassClipStack recorder =
18  EntityPassClipStack(Rect::MakeLTRB(0, 0, 100, 100));
19 
20  EXPECT_TRUE(recorder.GetReplayEntities().empty());
21 
22  Entity entity;
23  recorder.RecordEntity(entity, Contents::ClipCoverage::Type::kAppend,
24  Rect::MakeLTRB(0, 0, 100, 100));
25  EXPECT_EQ(recorder.GetReplayEntities().size(), 1u);
26 
27  recorder.RecordEntity(entity, Contents::ClipCoverage::Type::kAppend,
28  Rect::MakeLTRB(0, 0, 50, 50));
29  EXPECT_EQ(recorder.GetReplayEntities().size(), 2u);
30  ASSERT_TRUE(recorder.GetReplayEntities()[0].clip_coverage.has_value());
31  ASSERT_TRUE(recorder.GetReplayEntities()[1].clip_coverage.has_value());
32  // NOLINTBEGIN(bugprone-unchecked-optional-access)
33  EXPECT_EQ(recorder.GetReplayEntities()[0].clip_coverage.value(),
34  Rect::MakeLTRB(0, 0, 100, 100));
35  EXPECT_EQ(recorder.GetReplayEntities()[1].clip_coverage.value(),
36  Rect::MakeLTRB(0, 0, 50, 50));
37  // NOLINTEND(bugprone-unchecked-optional-access)
38 
39  recorder.RecordEntity(entity, Contents::ClipCoverage::Type::kRestore, Rect());
40  EXPECT_EQ(recorder.GetReplayEntities().size(), 1u);
41 
42  recorder.RecordEntity(entity, Contents::ClipCoverage::Type::kRestore, Rect());
43  EXPECT_TRUE(recorder.GetReplayEntities().empty());
44 }

References impeller::EntityPassClipStack::GetReplayEntities(), impeller::Contents::ClipCoverage::kAppend, impeller::Contents::ClipCoverage::kRestore, impeller::TRect< Scalar >::MakeLTRB(), and impeller::EntityPassClipStack::RecordEntity().

◆ TEST() [81/360]

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

Definition at line 160 of file entity_pass_unittests.cc.

160  {
161  EntityPassClipStack recorder =
162  EntityPassClipStack(Rect::MakeLTRB(0, 0, 100, 100));
163 
164  ASSERT_EQ(recorder.GetClipCoverageLayers().size(), 1u);
165 
166  // Push a clip.
167  Entity entity;
168  {
169  EntityPassClipStack::ClipStateResult result = recorder.ApplyClipState(
170  Contents::ClipCoverage{
171  .type = Contents::ClipCoverage::Type::kAppend,
172  .coverage = Rect::MakeLTRB(50, 50, 55, 55),
173  },
174  entity, 0, Point(0, 0));
175  EXPECT_TRUE(result.should_render);
176  EXPECT_TRUE(result.clip_did_change);
177  }
178 
179  ASSERT_EQ(recorder.GetClipCoverageLayers().size(), 2u);
180  EXPECT_EQ(recorder.GetClipCoverageLayers()[1].coverage,
181  Rect::MakeLTRB(50, 50, 55, 55));
182  EXPECT_EQ(recorder.GetClipCoverageLayers()[1].clip_height, 1u);
183  EXPECT_EQ(recorder.GetReplayEntities().size(), 1u);
184 
185  // Begin a subpass.
186  recorder.PushSubpass(Rect::MakeLTRB(50, 50, 55, 55), 1);
187  ASSERT_EQ(recorder.GetClipCoverageLayers().size(), 1u);
188  EXPECT_EQ(recorder.GetClipCoverageLayers()[0].coverage,
189  Rect::MakeLTRB(50, 50, 55, 55));
190 
191  {
192  EntityPassClipStack::ClipStateResult result = recorder.ApplyClipState(
193  Contents::ClipCoverage{
194  .type = Contents::ClipCoverage::Type::kAppend,
195  .coverage = Rect::MakeLTRB(54, 54, 55, 55),
196  },
197  entity, 0, Point(0, 0));
198  EXPECT_TRUE(result.should_render);
199  EXPECT_TRUE(result.clip_did_change);
200  }
201 
202  EXPECT_EQ(recorder.GetClipCoverageLayers()[1].coverage,
203  Rect::MakeLTRB(54, 54, 55, 55));
204 
205  // End subpass.
206  recorder.PopSubpass();
207 
208  EXPECT_EQ(recorder.GetClipCoverageLayers()[1].coverage,
209  Rect::MakeLTRB(50, 50, 55, 55));
210 }

References impeller::EntityPassClipStack::ApplyClipState(), impeller::EntityPassClipStack::ClipStateResult::clip_did_change, impeller::EntityPassClipStack::GetClipCoverageLayers(), impeller::EntityPassClipStack::GetReplayEntities(), impeller::Contents::ClipCoverage::kAppend, impeller::TRect< Scalar >::MakeLTRB(), impeller::EntityPassClipStack::PopSubpass(), impeller::EntityPassClipStack::PushSubpass(), impeller::EntityPassClipStack::ClipStateResult::should_render, and impeller::Contents::ClipCoverage::type.

◆ TEST() [82/360]

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

Definition at line 133 of file entity_pass_unittests.cc.

133  {
134  EntityPassClipStack recorder =
135  EntityPassClipStack(Rect::MakeLTRB(0, 0, 100, 100));
136 
137  ASSERT_EQ(recorder.GetClipCoverageLayers().size(), 1u);
138 
139  // Restore the clip.
140  Entity entity;
141  auto restore_clip = std::make_shared<ClipRestoreContents>();
142  restore_clip->SetRestoreHeight(0);
143  entity.SetContents(std::move(restore_clip));
144  EntityPassClipStack::ClipStateResult result = recorder.ApplyClipState(
145  Contents::ClipCoverage{
146  .type = Contents::ClipCoverage::Type::kRestore,
147  .coverage = Rect::MakeLTRB(50, 50, 55, 55),
148  },
149  entity, 0, Point(0, 0));
150  EXPECT_FALSE(result.should_render);
151  EXPECT_FALSE(result.clip_did_change);
152 
153  ASSERT_EQ(recorder.GetClipCoverageLayers().size(), 1u);
154  EXPECT_EQ(recorder.GetClipCoverageLayers()[0].coverage,
155  Rect::MakeSize(Size::MakeWH(100, 100)));
156  EXPECT_EQ(recorder.GetClipCoverageLayers()[0].clip_height, 0u);
157  EXPECT_EQ(recorder.GetReplayEntities().size(), 0u);
158 }

References impeller::EntityPassClipStack::ApplyClipState(), impeller::EntityPassClipStack::ClipStateResult::clip_did_change, impeller::EntityPassClipStack::GetClipCoverageLayers(), impeller::EntityPassClipStack::GetReplayEntities(), impeller::Contents::ClipCoverage::kRestore, impeller::TRect< Scalar >::MakeLTRB(), impeller::TRect< Scalar >::MakeSize(), impeller::TSize< Scalar >::MakeWH(), impeller::Entity::SetContents(), impeller::EntityPassClipStack::ClipStateResult::should_render, and impeller::Contents::ClipCoverage::type.

◆ TEST() [83/360]

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 }

◆ TEST() [84/360]

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 }

◆ TEST() [85/360]

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 }

◆ TEST() [86/360]

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 }

◆ TEST() [87/360]

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 }

◆ TEST() [88/360]

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

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  // Terminate the waiter.
120  waiter->Terminate();
121 
122  // Signal the fence.
123  raw_fence->SetStatus(vk::Result::eSuccess);
124 
125  // This will hang if the fence was not signalled.
126  signal.Wait();
127 }

◆ TEST() [90/360]

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

Definition at line 17 of file filter_input_unittests.cc.

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

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

◆ TEST() [91/360]

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

Definition at line 30 of file filter_input_unittests.cc.

30  {
31  std::shared_ptr<FilterContents> leaf =
32  ColorFilterContents::MakeBlend(BlendMode::kSource, {});
33  ASSERT_TRUE(leaf->IsLeaf());
34 
35  auto base = ColorFilterContents::MakeMatrixFilter(FilterInput::Make(leaf),
36  Matrix(), {});
37 
38  ASSERT_TRUE(leaf->IsLeaf());
39  ASSERT_FALSE(base->IsLeaf());
40 }

References impeller::kSource, impeller::FilterInput::Make(), impeller::ColorFilterContents::MakeBlend(), and impeller::FilterContents::MakeMatrixFilter().

◆ TEST() [92/360]

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

Definition at line 42 of file filter_input_unittests.cc.

42  {
43  std::shared_ptr<FilterContents> leaf =
44  ColorFilterContents::MakeBlend(BlendMode::kSource, {});
45  ASSERT_TRUE(leaf->IsLeaf());
46 
47  auto base = ColorFilterContents::MakeMatrixFilter(FilterInput::Make(leaf),
48  Matrix(), {});
49 
50  {
51  auto result = base->GetCoverage({});
52  ASSERT_FALSE(result.has_value());
53  }
54 
55  auto coverage_rect = Rect::MakeLTRB(100, 100, 200, 200);
56  base->SetLeafInputs(FilterInput::Make({coverage_rect}));
57 
58  {
59  auto result = base->GetCoverage({});
60  ASSERT_TRUE(result.has_value());
61  // NOLINTNEXTLINE(bugprone-unchecked-optional-access)
62  ASSERT_RECT_NEAR(result.value(), coverage_rect);
63  }
64 }

References ASSERT_RECT_NEAR, impeller::kSource, impeller::FilterInput::Make(), impeller::ColorFilterContents::MakeBlend(), impeller::TRect< Scalar >::MakeLTRB(), and impeller::FilterContents::MakeMatrixFilter().

◆ TEST() [93/360]

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

Definition at line 449 of file gaussian_blur_filter_contents_unittests.cc.

449  {
450  Scalar sigma = 1.0;
451  Scalar radius = GaussianBlurFilterContents::CalculateBlurRadius(
452  GaussianBlurFilterContents::ScaleSigma(sigma));
453  fml::StatusOr<Scalar> derived_sigma =
454  CalculateSigmaForBlurRadius(radius, Matrix());
455  ASSERT_TRUE(derived_sigma.ok());
456  EXPECT_NEAR(sigma, derived_sigma.value(), 0.01f);
457 }

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

◆ TEST() [94/360]

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

Definition at line 216 of file gaussian_blur_filter_contents_unittests.cc.

216  {
217  EXPECT_EQ(GaussianBlurFilterContents::CalculateScale(1.0f), 1);
218  EXPECT_EQ(GaussianBlurFilterContents::CalculateScale(2.0f), 1);
219  EXPECT_EQ(GaussianBlurFilterContents::CalculateScale(3.0f), 1);
220  EXPECT_EQ(GaussianBlurFilterContents::CalculateScale(4.0f), 1);
221  EXPECT_EQ(GaussianBlurFilterContents::CalculateScale(16.0f), 0.25);
222  // Hang on to 1/8 as long as possible.
223  EXPECT_EQ(GaussianBlurFilterContents::CalculateScale(95.0f), 0.125);
224  EXPECT_EQ(GaussianBlurFilterContents::CalculateScale(96.0f), 0.0625);
225  // Downsample clamped to 1/16th.
226  EXPECT_EQ(GaussianBlurFilterContents::CalculateScale(1024.0f), 0.0625);
227 }

References impeller::GaussianBlurFilterContents::CalculateScale().

◆ TEST() [95/360]

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

Definition at line 615 of file gaussian_blur_filter_contents_unittests.cc.

615  {
616  Scalar sigma = 30.5f;
617  int32_t blur_radius = static_cast<int32_t>(
618  std::ceil(GaussianBlurFilterContents::CalculateBlurRadius(sigma)));
619  BlurParameters parameters = {.blur_uv_offset = Point(1, 0),
620  .blur_sigma = sigma,
621  .blur_radius = blur_radius,
622  .step_size = 1};
623  KernelSamples kernel_samples = GenerateBlurInfo(parameters);
624  GaussianBlurPipeline::FragmentShader::KernelSamples frag_kernel_samples =
625  LerpHackKernelSamples(kernel_samples);
626  EXPECT_TRUE(frag_kernel_samples.sample_count <= kGaussianBlurMaxKernelSize);
627 }

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

◆ TEST() [96/360]

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

Definition at line 459 of file gaussian_blur_filter_contents_unittests.cc.

459  {
460  BlurParameters parameters = {.blur_uv_offset = Point(1, 0),
461  .blur_sigma = 1,
462  .blur_radius = 5,
463  .step_size = 1};
464  KernelSamples samples = GenerateBlurInfo(parameters);
465  EXPECT_EQ(samples.sample_count, 9);
466 
467  // Coefficients should add up to 1.
468  Scalar tally = 0;
469  for (int i = 0; i < samples.sample_count; ++i) {
470  tally += samples.samples[i].coefficient;
471  }
472  EXPECT_FLOAT_EQ(tally, 1.0f);
473 
474  // Verify the shape of the curve.
475  for (int i = 0; i < 4; ++i) {
476  EXPECT_FLOAT_EQ(samples.samples[i].coefficient,
477  samples.samples[8 - i].coefficient);
478  EXPECT_TRUE(samples.samples[i + 1].coefficient >
479  samples.samples[i].coefficient);
480  }
481 }

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

◆ TEST() [97/360]

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

Definition at line 112 of file gaussian_blur_filter_contents_unittests.cc.

112  {
113  GaussianBlurFilterContents contents(
114  /*sigma_x=*/0.0, /*sigma_y=*/0.0, Entity::TileMode::kDecal,
115  FilterContents::BlurStyle::kNormal, /*mask_geometry=*/nullptr);
116  FilterInput::Vector inputs = {};
117  Entity entity;
118  std::optional<Rect> coverage =
119  contents.GetFilterCoverage(inputs, entity, /*effect_transform=*/Matrix());
120  ASSERT_FALSE(coverage.has_value());
121 }

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

◆ TEST() [98/360]

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

Definition at line 123 of file gaussian_blur_filter_contents_unittests.cc.

123  {
124  GaussianBlurFilterContents contents(
125  /*sigma_x=*/0.0, /*sigma_y=*/0.0, Entity::TileMode::kDecal,
126  FilterContents::BlurStyle::kNormal, /*mask_geometry=*/nullptr);
127  FilterInput::Vector inputs = {
128  FilterInput::Make(Rect::MakeLTRB(10, 10, 110, 110))};
129  Entity entity;
130  std::optional<Rect> coverage =
131  contents.GetFilterCoverage(inputs, entity, /*effect_transform=*/Matrix());
132 
133  ASSERT_EQ(coverage, Rect::MakeLTRB(10, 10, 110, 110));
134 }

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

◆ TEST() [99/360]

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

Definition at line 136 of file gaussian_blur_filter_contents_unittests.cc.

136  {
137  fml::StatusOr<Scalar> sigma_radius_1 =
138  CalculateSigmaForBlurRadius(1.0, Matrix());
139  ASSERT_TRUE(sigma_radius_1.ok());
140  GaussianBlurFilterContents contents(
141  /*sigma_x=*/sigma_radius_1.value(),
142  /*sigma_y=*/sigma_radius_1.value(), Entity::TileMode::kDecal,
143  FilterContents::BlurStyle::kNormal, /*mask_geometry=*/nullptr);
144  FilterInput::Vector inputs = {
145  FilterInput::Make(Rect::MakeLTRB(100, 100, 200, 200))};
146  Entity entity;
147  std::optional<Rect> coverage =
148  contents.GetFilterCoverage(inputs, entity, /*effect_transform=*/Matrix());
149 
150  EXPECT_TRUE(coverage.has_value());
151  if (coverage.has_value()) {
152  EXPECT_RECT_NEAR(coverage.value(), Rect::MakeLTRB(99, 99, 201, 201));
153  }
154 }

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

◆ TEST() [100/360]

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

Definition at line 104 of file gaussian_blur_filter_contents_unittests.cc.

104  {
105  GaussianBlurFilterContents contents(
106  /*sigma_x=*/0.0, /*sigma_y=*/0.0, Entity::TileMode::kDecal,
107  FilterContents::BlurStyle::kNormal, /*mask_geometry=*/nullptr);
108  EXPECT_EQ(contents.GetSigmaX(), 0.0);
109  EXPECT_EQ(contents.GetSigmaY(), 0.0);
110 }

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

◆ TEST() [101/360]

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

Definition at line 199 of file gaussian_blur_filter_contents_unittests.cc.

199  {
200  fml::StatusOr<Scalar> sigma_radius_1 =
201  CalculateSigmaForBlurRadius(1.0, Matrix());
202  ASSERT_TRUE(sigma_radius_1.ok());
203  auto contents = std::make_unique<GaussianBlurFilterContents>(
204  sigma_radius_1.value(), sigma_radius_1.value(), Entity::TileMode::kDecal,
205  FilterContents::BlurStyle::kNormal, /*mask_geometry=*/nullptr);
206  std::optional<Rect> coverage = contents->GetFilterSourceCoverage(
207  /*effect_transform=*/Matrix::MakeScale({2.0, 2.0, 1.0}),
208  /*output_limit=*/Rect::MakeLTRB(100, 100, 200, 200));
209  EXPECT_TRUE(coverage.has_value());
210  if (coverage.has_value()) {
211  EXPECT_RECT_NEAR(coverage.value(),
212  Rect::MakeLTRB(100 - 2, 100 - 2, 200 + 2, 200 + 2));
213  }
214 }

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

◆ TEST() [102/360]

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

Definition at line 561 of file gaussian_blur_filter_contents_unittests.cc.

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

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

◆ TEST() [103/360]

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

Definition at line 483 of file gaussian_blur_filter_contents_unittests.cc.

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

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

◆ TEST() [104/360]

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

Definition at line 1678 of file geometry_unittests.cc.

1678  {
1679  using BlendT = std::underlying_type_t<BlendMode>;
1680  for (BlendT i = 0; i <= static_cast<BlendT>(BlendMode::kLast); i++) {
1681  auto mode = static_cast<BlendMode>(i);
1682  auto result = BlendModeToString(mode);
1684  }
1685 }

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

◆ TEST() [105/360]

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

Definition at line 1687 of file geometry_unittests.cc.

1687  {
1688  {
1689  auto deg = Degrees{90.0};
1690  Radians rad = deg;
1691  ASSERT_FLOAT_EQ(rad.radians, kPiOver2);
1692  }
1693 }

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

◆ TEST() [106/360]

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

Definition at line 608 of file geometry_unittests.cc.

608  {
609  {
610  Point p1(1.0, 2.0);
611  IPoint p2 = static_cast<IPoint>(p1);
612  ASSERT_EQ(p2.x, 1u);
613  ASSERT_EQ(p2.y, 2u);
614  }
615 
616  {
617  Size s1(1.0, 2.0);
618  ISize s2 = static_cast<ISize>(s1);
619  ASSERT_EQ(s2.width, 1u);
620  ASSERT_EQ(s2.height, 2u);
621  }
622 
623  {
624  Size s1(1.0, 2.0);
625  Point p1 = static_cast<Point>(s1);
626  ASSERT_EQ(p1.x, 1u);
627  ASSERT_EQ(p1.y, 2u);
628  }
629 }

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

◆ TEST() [107/360]

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

Definition at line 595 of file geometry_unittests.cc.

595  {
596  ASSERT_EQ((Size{128, 128}.MipCount()), 7u);
597  ASSERT_EQ((Size{128, 256}.MipCount()), 8u);
598  ASSERT_EQ((Size{128, 130}.MipCount()), 8u);
599  ASSERT_EQ((Size{128, 257}.MipCount()), 9u);
600  ASSERT_EQ((Size{257, 128}.MipCount()), 9u);
601  ASSERT_EQ((Size{128, 0}.MipCount()), 1u);
602  ASSERT_EQ((Size{128, -25}.MipCount()), 1u);
603  ASSERT_EQ((Size{-128, 25}.MipCount()), 1u);
604  ASSERT_EQ((Size{1, 1}.MipCount()), 1u);
605  ASSERT_EQ((Size{0, 0}.MipCount()), 1u);
606 }

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

◆ TEST() [108/360]

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

Definition at line 631 of file geometry_unittests.cc.

631  {
632  {
633  IPoint p1(1, 2);
634  IPoint p2 = p1 + IPoint(1, 2);
635  ASSERT_EQ(p2.x, 2u);
636  ASSERT_EQ(p2.y, 4u);
637  }
638 
639  {
640  IPoint p1(3, 6);
641  IPoint p2 = p1 - IPoint(1, 2);
642  ASSERT_EQ(p2.x, 2u);
643  ASSERT_EQ(p2.y, 4u);
644  }
645 
646  {
647  IPoint p1(1, 2);
648  IPoint p2 = p1 * IPoint(2, 3);
649  ASSERT_EQ(p2.x, 2u);
650  ASSERT_EQ(p2.y, 6u);
651  }
652 
653  {
654  IPoint p1(2, 6);
655  IPoint p2 = p1 / IPoint(2, 3);
656  ASSERT_EQ(p2.x, 1u);
657  ASSERT_EQ(p2.y, 2u);
658  }
659 }

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

◆ TEST() [109/360]

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

Definition at line 661 of file geometry_unittests.cc.

661  {
662  // LHS
663  {
664  IPoint p1(1, 2);
665  IPoint p2 = p1 * 2.0f;
666  ASSERT_EQ(p2.x, 2u);
667  ASSERT_EQ(p2.y, 4u);
668  }
669 
670  {
671  IPoint p1(2, 6);
672  IPoint p2 = p1 / 2.0f;
673  ASSERT_EQ(p2.x, 1u);
674  ASSERT_EQ(p2.y, 3u);
675  }
676 
677  // RHS
678  {
679  IPoint p1(1, 2);
680  IPoint p2 = 2.0f * p1;
681  ASSERT_EQ(p2.x, 2u);
682  ASSERT_EQ(p2.y, 4u);
683  }
684 
685  {
686  IPoint p1(2, 6);
687  IPoint p2 = 12.0f / p1;
688  ASSERT_EQ(p2.x, 6u);
689  ASSERT_EQ(p2.y, 2u);
690  }
691 }

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

◆ TEST() [110/360]

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

Definition at line 1245 of file geometry_unittests.cc.

1245  {
1246  {
1247  Vector3 p1(1, 2, 3);
1248  Vector3 p2 = p1 + Vector3(1, 2, 3);
1249  ASSERT_EQ(p2.x, 2u);
1250  ASSERT_EQ(p2.y, 4u);
1251  ASSERT_EQ(p2.z, 6u);
1252  }
1253 
1254  {
1255  Vector3 p1(3, 6, 9);
1256  Vector3 p2 = p1 - Vector3(1, 2, 3);
1257  ASSERT_EQ(p2.x, 2u);
1258  ASSERT_EQ(p2.y, 4u);
1259  ASSERT_EQ(p2.z, 6u);
1260  }
1261 
1262  {
1263  Vector3 p1(1, 2, 3);
1264  Vector3 p2 = p1 * Vector3(2, 3, 4);
1265  ASSERT_EQ(p2.x, 2u);
1266  ASSERT_EQ(p2.y, 6u);
1267  ASSERT_EQ(p2.z, 12u);
1268  }
1269 
1270  {
1271  Vector3 p1(2, 6, 12);
1272  Vector3 p2 = p1 / Vector3(2, 3, 4);
1273  ASSERT_EQ(p2.x, 1u);
1274  ASSERT_EQ(p2.y, 2u);
1275  ASSERT_EQ(p2.z, 3u);
1276  }
1277 }

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

◆ TEST() [111/360]

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

Definition at line 1279 of file geometry_unittests.cc.

1279  {
1280  // LHS
1281  {
1282  Vector3 p1(1, 2, 3);
1283  Vector3 p2 = p1 + 2.0f;
1284  ASSERT_EQ(p2.x, 3);
1285  ASSERT_EQ(p2.y, 4);
1286  ASSERT_EQ(p2.z, 5);
1287  }
1288 
1289  {
1290  Vector3 p1(1, 2, 3);
1291  Vector3 p2 = p1 - 2.0f;
1292  ASSERT_EQ(p2.x, -1);
1293  ASSERT_EQ(p2.y, 0);
1294  ASSERT_EQ(p2.z, 1);
1295  }
1296 
1297  {
1298  Vector3 p1(1, 2, 3);
1299  Vector3 p2 = p1 * 2.0f;
1300  ASSERT_EQ(p2.x, 2);
1301  ASSERT_EQ(p2.y, 4);
1302  ASSERT_EQ(p2.z, 6);
1303  }
1304 
1305  {
1306  Vector3 p1(2, 6, 12);
1307  Vector3 p2 = p1 / 2.0f;
1308  ASSERT_EQ(p2.x, 1);
1309  ASSERT_EQ(p2.y, 3);
1310  ASSERT_EQ(p2.z, 6);
1311  }
1312 
1313  // RHS
1314  {
1315  Vector3 p1(1, 2, 3);
1316  Vector3 p2 = 2.0f + p1;
1317  ASSERT_EQ(p2.x, 3);
1318  ASSERT_EQ(p2.y, 4);
1319  ASSERT_EQ(p2.z, 5);
1320  }
1321 
1322  {
1323  Vector3 p1(1, 2, 3);
1324  Vector3 p2 = 2.0f - p1;
1325  ASSERT_EQ(p2.x, 1);
1326  ASSERT_EQ(p2.y, 0);
1327  ASSERT_EQ(p2.z, -1);
1328  }
1329 
1330  {
1331  Vector3 p1(1, 2, 3);
1332  Vector3 p2 = 2.0f * p1;
1333  ASSERT_EQ(p2.x, 2);
1334  ASSERT_EQ(p2.y, 4);
1335  ASSERT_EQ(p2.z, 6);
1336  }
1337 
1338  {
1339  Vector3 p1(2, 6, 12);
1340  Vector3 p2 = 12.0f / p1;
1341  ASSERT_EQ(p2.x, 6);
1342  ASSERT_EQ(p2.y, 2);
1343  ASSERT_EQ(p2.z, 1);
1344  }
1345 }

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

◆ TEST() [112/360]

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

Definition at line 813 of file geometry_unittests.cc.

813  {
814  // Point on RHS
815  {
816  IPoint p(1, 2);
817  p += IPoint(1, 2);
818  ASSERT_EQ(p.x, 2u);
819  ASSERT_EQ(p.y, 4u);
820  }
821 
822  {
823  IPoint p(3, 6);
824  p -= IPoint(1, 2);
825  ASSERT_EQ(p.x, 2u);
826  ASSERT_EQ(p.y, 4u);
827  }
828 
829  {
830  IPoint p(1, 2);
831  p *= IPoint(2, 3);
832  ASSERT_EQ(p.x, 2u);
833  ASSERT_EQ(p.y, 6u);
834  }
835 
836  {
837  IPoint p(2, 6);
838  p /= IPoint(2, 3);
839  ASSERT_EQ(p.x, 1u);
840  ASSERT_EQ(p.y, 2u);
841  }
842 
843  // Size on RHS
844  {
845  IPoint p(1, 2);
846  p += ISize(1, 2);
847  ASSERT_EQ(p.x, 2u);
848  ASSERT_EQ(p.y, 4u);
849  }
850 
851  {
852  IPoint p(3, 6);
853  p -= ISize(1, 2);
854  ASSERT_EQ(p.x, 2u);
855  ASSERT_EQ(p.y, 4u);
856  }
857 
858  {
859  IPoint p(1, 2);
860  p *= ISize(2, 3);
861  ASSERT_EQ(p.x, 2u);
862  ASSERT_EQ(p.y, 6u);
863  }
864 
865  {
866  IPoint p(2, 6);
867  p /= ISize(2, 3);
868  ASSERT_EQ(p.x, 1u);
869  ASSERT_EQ(p.y, 2u);
870  }
871 
872  // Arithmetic type on RHS
873  {
874  IPoint p(1, 2);
875  p *= 3;
876  ASSERT_EQ(p.x, 3u);
877  ASSERT_EQ(p.y, 6u);
878  }
879 
880  {
881  IPoint p(3, 6);
882  p /= 3;
883  ASSERT_EQ(p.x, 1u);
884  ASSERT_EQ(p.y, 2u);
885  }
886 }

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

◆ TEST() [113/360]

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

Definition at line 1195 of file geometry_unittests.cc.

1195  {
1196  {
1197  Vector3 p(1, 2, 4);
1198  p += Vector3(1, 2, 4);
1199  ASSERT_EQ(p.x, 2u);
1200  ASSERT_EQ(p.y, 4u);
1201  ASSERT_EQ(p.z, 8u);
1202  }
1203 
1204  {
1205  Vector3 p(3, 6, 8);
1206  p -= Vector3(1, 2, 3);
1207  ASSERT_EQ(p.x, 2u);
1208  ASSERT_EQ(p.y, 4u);
1209  ASSERT_EQ(p.z, 5u);
1210  }
1211 
1212  {
1213  Vector3 p(1, 2, 3);
1214  p *= Vector3(2, 3, 4);
1215  ASSERT_EQ(p.x, 2u);
1216  ASSERT_EQ(p.y, 6u);
1217  ASSERT_EQ(p.z, 12u);
1218  }
1219 
1220  {
1221  Vector3 p(1, 2, 3);
1222  p *= 2;
1223  ASSERT_EQ(p.x, 2u);
1224  ASSERT_EQ(p.y, 4u);
1225  ASSERT_EQ(p.z, 6u);
1226  }
1227 
1228  {
1229  Vector3 p(2, 6, 12);
1230  p /= Vector3(2, 3, 4);
1231  ASSERT_EQ(p.x, 1u);
1232  ASSERT_EQ(p.y, 2u);
1233  ASSERT_EQ(p.z, 3u);
1234  }
1235 
1236  {
1237  Vector3 p(2, 6, 12);
1238  p /= 2;
1239  ASSERT_EQ(p.x, 1u);
1240  ASSERT_EQ(p.y, 3u);
1241  ASSERT_EQ(p.z, 6u);
1242  }
1243 }

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

◆ TEST() [114/360]

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

Definition at line 1452 of file geometry_unittests.cc.

1452  {
1453  {
1454  ColorMatrix color_matrix = {
1455  1, 1, 1, 1, 1, //
1456  1, 1, 1, 1, 1, //
1457  1, 1, 1, 1, 1, //
1458  1, 1, 1, 1, 1, //
1459  };
1460  auto result = Color::White().ApplyColorMatrix(color_matrix);
1461  auto expected = Color(1, 1, 1, 1);
1462  ASSERT_COLOR_NEAR(result, expected);
1463  }
1464 
1465  {
1466  ColorMatrix color_matrix = {
1467  0.1, 0, 0, 0, 0.01, //
1468  0, 0.2, 0, 0, 0.02, //
1469  0, 0, 0.3, 0, 0.03, //
1470  0, 0, 0, 0.4, 0.04, //
1471  };
1472  auto result = Color::White().ApplyColorMatrix(color_matrix);
1473  auto expected = Color(0.11, 0.22, 0.33, 0.44);
1474  ASSERT_COLOR_NEAR(result, expected);
1475  }
1476 }

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

◆ TEST() [115/360]

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

Definition at line 1661 of file geometry_unittests.cc.

1661  {
1662  Color dst = ColorBlendTestData::kDestinationColor;
1663  for (size_t source_i = 0;
1664  source_i < sizeof(ColorBlendTestData::kSourceColors) / sizeof(Color);
1665  source_i++) {
1666  Color src = ColorBlendTestData::kSourceColors[source_i];
1667 
1668  Color expected;
1670  }
1671 }

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

◆ TEST() [116/360]

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

Definition at line 1412 of file geometry_unittests.cc.

1412  {
1413  {
1414  Color result = Color(0.5, 0.5, 0.5, 0.5).Clamp01();
1415  Color expected = Color(0.5, 0.5, 0.5, 0.5);
1416  ASSERT_COLOR_NEAR(result, expected);
1417  }
1418 
1419  {
1420  Color result = Color(-1, -1, -1, -1).Clamp01();
1421  Color expected = Color(0, 0, 0, 0);
1422  ASSERT_COLOR_NEAR(result, expected);
1423  }
1424 
1425  {
1426  Color result = Color(2, 2, 2, 2).Clamp01();
1427  Color expected = Color(1, 1, 1, 1);
1428  ASSERT_COLOR_NEAR(result, expected);
1429  }
1430 }

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

◆ TEST() [117/360]

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

Definition at line 1390 of file geometry_unittests.cc.

1390  {
1391  {
1392  Color a(0.0, 0.0, 0.0, 0.0);
1393  Color b(1.0, 1.0, 1.0, 1.0);
1394 
1395  ASSERT_COLOR_NEAR(Color::Lerp(a, b, 0.5), Color(0.5, 0.5, 0.5, 0.5));
1396  ASSERT_COLOR_NEAR(Color::Lerp(a, b, 0.0), a);
1397  ASSERT_COLOR_NEAR(Color::Lerp(a, b, 1.0), b);
1398  ASSERT_COLOR_NEAR(Color::Lerp(a, b, 0.2), Color(0.2, 0.2, 0.2, 0.2));
1399  }
1400 
1401  {
1402  Color a(0.2, 0.4, 1.0, 0.5);
1403  Color b(0.4, 1.0, 0.2, 0.3);
1404 
1405  ASSERT_COLOR_NEAR(Color::Lerp(a, b, 0.5), Color(0.3, 0.7, 0.6, 0.4));
1406  ASSERT_COLOR_NEAR(Color::Lerp(a, b, 0.0), a);
1407  ASSERT_COLOR_NEAR(Color::Lerp(a, b, 1.0), b);
1408  ASSERT_COLOR_NEAR(Color::Lerp(a, b, 0.2), Color(0.24, 0.52, 0.84, 0.46));
1409  }
1410 }

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

◆ TEST() [118/360]

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

Definition at line 1478 of file geometry_unittests.cc.

1478  {
1479  {
1480  auto result = Color::White().LinearToSRGB();
1481  auto expected = Color(1, 1, 1, 1);
1482  ASSERT_COLOR_NEAR(result, expected);
1483  }
1484 
1485  {
1486  auto result = Color::BlackTransparent().LinearToSRGB();
1487  auto expected = Color(0, 0, 0, 0);
1488  ASSERT_COLOR_NEAR(result, expected);
1489  }
1490 
1491  {
1492  auto result = Color(0.2, 0.4, 0.6, 0.8).LinearToSRGB();
1493  auto expected = Color(0.484529, 0.665185, 0.797738, 0.8);
1494  ASSERT_COLOR_NEAR(result, expected);
1495  }
1496 }

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

◆ TEST() [119/360]

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

Definition at line 1432 of file geometry_unittests.cc.

1432  {
1433  {
1434  Color a = Color::MakeRGBA8(0, 0, 0, 0);
1435  Color b = Color::BlackTransparent();
1436  ASSERT_COLOR_NEAR(a, b);
1437  }
1438 
1439  {
1440  Color a = Color::MakeRGBA8(255, 255, 255, 255);
1441  Color b = Color::White();
1442  ASSERT_COLOR_NEAR(a, b);
1443  }
1444 
1445  {
1446  Color a = Color::MakeRGBA8(63, 127, 191, 127);
1447  Color b(0.247059, 0.498039, 0.74902, 0.498039);
1448  ASSERT_COLOR_NEAR(a, b);
1449  }
1450 }

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

◆ TEST() [120/360]

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

Definition at line 1347 of file geometry_unittests.cc.

1347  {
1348  {
1349  Color a(1.0, 0.5, 0.2, 0.5);
1350  Color premultiplied = a.Premultiply();
1351  Color expected = Color(0.5, 0.25, 0.1, 0.5);
1352  ASSERT_COLOR_NEAR(premultiplied, expected);
1353  }
1354 
1355  {
1356  Color a(0.5, 0.25, 0.1, 0.5);
1357  Color unpremultiplied = a.Unpremultiply();
1358  Color expected = Color(1.0, 0.5, 0.2, 0.5);
1359  ASSERT_COLOR_NEAR(unpremultiplied, expected);
1360  }
1361 
1362  {
1363  Color a(0.5, 0.25, 0.1, 0.0);
1364  Color unpremultiplied = a.Unpremultiply();
1365  Color expected = Color(0.0, 0.0, 0.0, 0.0);
1366  ASSERT_COLOR_NEAR(unpremultiplied, expected);
1367  }
1368 }

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

◆ TEST() [121/360]

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

Definition at line 1770 of file geometry_unittests.cc.

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

◆ TEST() [122/360]

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

Definition at line 1370 of file geometry_unittests.cc.

1370  {
1371  {
1372  Color a(1.0, 0.5, 0.2, 0.5);
1373  std::array<uint8_t, 4> expected = {255, 128, 51, 128};
1374  ASSERT_ARRAY_4_NEAR(a.ToR8G8B8A8(), expected);
1375  }
1376 
1377  {
1378  Color a(0.0, 0.0, 0.0, 0.0);
1379  std::array<uint8_t, 4> expected = {0, 0, 0, 0};
1380  ASSERT_ARRAY_4_NEAR(a.ToR8G8B8A8(), expected);
1381  }
1382 
1383  {
1384  Color a(1.0, 1.0, 1.0, 1.0);
1385  std::array<uint8_t, 4> expected = {255, 255, 255, 255};
1386  ASSERT_ARRAY_4_NEAR(a.ToR8G8B8A8(), expected);
1387  }
1388 }

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

◆ TEST() [123/360]

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

Definition at line 1498 of file geometry_unittests.cc.

1498  {
1499  {
1500  auto result = Color::White().SRGBToLinear();
1501  auto expected = Color(1, 1, 1, 1);
1502  ASSERT_COLOR_NEAR(result, expected);
1503  }
1504 
1505  {
1506  auto result = Color::BlackTransparent().SRGBToLinear();
1507  auto expected = Color(0, 0, 0, 0);
1508  ASSERT_COLOR_NEAR(result, expected);
1509  }
1510 
1511  {
1512  auto result = Color(0.2, 0.4, 0.6, 0.8).SRGBToLinear();
1513  auto expected = Color(0.0331048, 0.132868, 0.318547, 0.8);
1514  ASSERT_COLOR_NEAR(result, expected);
1515  }
1516 }

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

◆ TEST() [124/360]

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

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

Definition at line 1792 of file geometry_unittests.cc.

1792  {
1793  {
1794  // Simple 2 color gradient produces color buffer containing exactly those
1795  // values.
1796  std::vector<Color> colors = {Color::Red(), Color::Blue()};
1797  std::vector<Scalar> stops = {0.0, 1.0};
1798 
1799  auto gradient = CreateGradientBuffer(colors, stops);
1800 
1801  ASSERT_COLOR_BUFFER_NEAR(gradient.color_bytes, colors);
1802  ASSERT_EQ(gradient.texture_size, 2u);
1803  }
1804 
1805  {
1806  // Gradient with duplicate stops does not create an empty texture.
1807  std::vector<Color> colors = {Color::Red(), Color::Yellow(), Color::Black(),
1808  Color::Blue()};
1809  std::vector<Scalar> stops = {0.0, 0.25, 0.25, 1.0};
1810 
1811  auto gradient = CreateGradientBuffer(colors, stops);
1812  ASSERT_EQ(gradient.texture_size, 5u);
1813  }
1814 
1815  {
1816  // Simple N color gradient produces color buffer containing exactly those
1817  // values.
1818  std::vector<Color> colors = {Color::Red(), Color::Blue(), Color::Green(),
1819  Color::White()};
1820  std::vector<Scalar> stops = {0.0, 0.33, 0.66, 1.0};
1821 
1822  auto gradient = CreateGradientBuffer(colors, stops);
1823 
1824  ASSERT_COLOR_BUFFER_NEAR(gradient.color_bytes, colors);
1825  ASSERT_EQ(gradient.texture_size, 4u);
1826  }
1827 
1828  {
1829  // Gradient with color stops will lerp and scale buffer.
1830  std::vector<Color> colors = {Color::Red(), Color::Blue(), Color::Green()};
1831  std::vector<Scalar> stops = {0.0, 0.25, 1.0};
1832 
1833  auto gradient = CreateGradientBuffer(colors, stops);
1834 
1835  std::vector<Color> lerped_colors = {
1836  Color::Red(),
1837  Color::Blue(),
1838  Color::Lerp(Color::Blue(), Color::Green(), 0.3333),
1839  Color::Lerp(Color::Blue(), Color::Green(), 0.6666),
1840  Color::Green(),
1841  };
1842  ASSERT_COLOR_BUFFER_NEAR(gradient.color_bytes, lerped_colors);
1843  ASSERT_EQ(gradient.texture_size, 5u);
1844  }
1845 
1846  {
1847  // Gradient size is capped at 1024.
1848  std::vector<Color> colors = {};
1849  std::vector<Scalar> stops = {};
1850  for (auto i = 0u; i < 1025; i++) {
1851  colors.push_back(Color::Blue());
1852  stops.push_back(i / 1025.0);
1853  }
1854 
1855  auto gradient = CreateGradientBuffer(colors, stops);
1856 
1857  ASSERT_EQ(gradient.texture_size, 1024u);
1858  ASSERT_EQ(gradient.color_bytes.size(), 1024u * 4);
1859  }
1860 }

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

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

Definition at line 1862 of file geometry_unittests.cc.

1862  {
1863 #if defined(FML_OS_MACOSX) || defined(FML_OS_IOS) || \
1864  defined(FML_OS_IOS_SIMULATOR)
1865  ASSERT_EQ(ScalarToHalf(0.0), 0.0f16);
1866  ASSERT_EQ(ScalarToHalf(0.05), 0.05f16);
1867  ASSERT_EQ(ScalarToHalf(2.43), 2.43f16);
1868  ASSERT_EQ(ScalarToHalf(-1.45), -1.45f16);
1869 
1870  // 65504 is the largest possible half.
1871  ASSERT_EQ(ScalarToHalf(65504.0f), 65504.0f16);
1872  ASSERT_EQ(ScalarToHalf(65504.0f + 1), 65504.0f16);
1873 
1874  // Colors
1875  ASSERT_EQ(HalfVector4(Color::Red()),
1876  HalfVector4(1.0f16, 0.0f16, 0.0f16, 1.0f16));
1877  ASSERT_EQ(HalfVector4(Color::Green()),
1878  HalfVector4(0.0f16, 1.0f16, 0.0f16, 1.0f16));
1879  ASSERT_EQ(HalfVector4(Color::Blue()),
1880  HalfVector4(0.0f16, 0.0f16, 1.0f16, 1.0f16));
1881  ASSERT_EQ(HalfVector4(Color::Black().WithAlpha(0)),
1882  HalfVector4(0.0f16, 0.0f16, 0.0f16, 0.0f16));
1883 
1884  ASSERT_EQ(HalfVector3(Vector3(4.0, 6.0, -1.0)),
1885  HalfVector3(4.0f16, 6.0f16, -1.0f16));
1886  ASSERT_EQ(HalfVector2(Vector2(4.0, 6.0)), HalfVector2(4.0f16, 6.0f16));
1887 
1888  ASSERT_EQ(Half(0.5f), Half(0.5f16));
1889  ASSERT_EQ(Half(0.5), Half(0.5f16));
1890  ASSERT_EQ(Half(5), Half(5.0f16));
1891 #else
1892  GTEST_SKIP() << "Half-precision floats (IEEE 754) are not portable and "
1893  "only used on Apple platforms.";
1894 #endif // FML_OS_MACOSX || FML_OS_IOS || FML_OS_IOS_SIMULATOR
1895 }

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

◆ TEST() [127/360]

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

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 }

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

◆ TEST() [129/360]

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

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

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

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

Definition at line 423 of file geometry_unittests.cc.

423  {
424  {
425  auto m = Matrix();
426  Vector3 x = m.GetBasisX();
427  Vector3 y = m.GetBasisY();
428  Vector3 z = m.GetBasisZ();
429  ASSERT_VECTOR3_NEAR(x, Vector3(1, 0, 0));
430  ASSERT_VECTOR3_NEAR(y, Vector3(0, 1, 0));
431  ASSERT_VECTOR3_NEAR(z, Vector3(0, 0, 1));
432  }
433 
434  {
435  auto m = Matrix::MakeRotationZ(Radians{kPiOver2}) *
436  Matrix::MakeRotationX(Radians{kPiOver2}) *
437  Matrix::MakeScale(Vector3(2, 3, 4));
438  Vector3 x = m.GetBasisX();
439  Vector3 y = m.GetBasisY();
440  Vector3 z = m.GetBasisZ();
441  ASSERT_VECTOR3_NEAR(x, Vector3(0, 2, 0));
442  ASSERT_VECTOR3_NEAR(y, Vector3(0, 0, 3));
443  ASSERT_VECTOR3_NEAR(z, Vector3(4, 0, 0));
444  }
445 }

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

◆ TEST() [133/360]

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

Definition at line 447 of file geometry_unittests.cc.

447  {
448  {
449  auto m = Matrix();
450  Scalar result = m.GetDirectionScale(Vector3{1, 0, 0});
451  ASSERT_FLOAT_EQ(result, 1);
452  }
453 
454  {
455  auto m = Matrix::MakeRotationX(Degrees{10}) *
456  Matrix::MakeRotationY(Degrees{83}) *
457  Matrix::MakeRotationZ(Degrees{172});
458  Scalar result = m.GetDirectionScale(Vector3{0, 1, 0});
459  ASSERT_FLOAT_EQ(result, 1);
460  }
461 
462  {
463  auto m = Matrix::MakeRotationZ(Radians{kPiOver2}) *
464  Matrix::MakeScale(Vector3(3, 4, 5));
465  Scalar result = m.GetDirectionScale(Vector3{2, 0, 0});
466  ASSERT_FLOAT_EQ(result, 8);
467  }
468 }

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

◆ TEST() [134/360]

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

Definition at line 333 of file geometry_unittests.cc.

333  {
334  {
335  auto m = Matrix::MakeScale({3, 1, 1});
336  ASSERT_EQ(m.GetMaxBasisLength(), 3);
337 
338  m = m * Matrix::MakeSkew(0, 4);
339  ASSERT_EQ(m.GetMaxBasisLength(), 5);
340  }
341 
342  {
343  auto m = Matrix::MakeScale({-3, 4, 2});
344  ASSERT_EQ(m.GetMaxBasisLength(), 4);
345  }
346 }

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

◆ TEST() [135/360]

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

Definition at line 348 of file geometry_unittests.cc.

348  {
349  {
350  auto m = Matrix::MakeScale({3, 1, 1});
351  ASSERT_EQ(m.GetMaxBasisLengthXY(), 3);
352 
353  m = m * Matrix::MakeSkew(0, 4);
354  ASSERT_EQ(m.GetMaxBasisLengthXY(), 5);
355  }
356 
357  {
358  auto m = Matrix::MakeScale({-3, 4, 7});
359  ASSERT_EQ(m.GetMaxBasisLengthXY(), 4);
360  }
361 
362  {
363  // clang-format off
364  auto m = Matrix::MakeColumn(
365  1.0f, 0.0f, 0.0f, 0.0f,
366  0.0f, 1.0f, 0.0f, 0.0f,
367  4.0f, 0.0f, 1.0f, 0.0f,
368  0.0f, 0.0f, 0.0f, 1.0f
369  );
370  // clang-format on
371  ASSERT_EQ(m.GetMaxBasisLengthXY(), 1.0f);
372  }
373 }

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

◆ TEST() [136/360]

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

Definition at line 496 of file geometry_unittests.cc.

496  {
497  {
498  auto m = Matrix::MakeLookAt(Vector3(0, 0, -1), Vector3(0, 0, 1),
499  Vector3(0, 1, 0));
500  auto expected = Matrix{
501  1, 0, 0, 0, //
502  0, 1, 0, 0, //
503  0, 0, 1, 0, //
504  0, 0, 1, 1, //
505  };
506  ASSERT_MATRIX_NEAR(m, expected);
507  }
508 
509  // Sideways tilt.
510  {
511  auto m = Matrix::MakeLookAt(Vector3(0, 0, -1), Vector3(0, 0, 1),
512  Vector3(1, 1, 0).Normalize());
513 
514  // clang-format off
515  auto expected = Matrix{
516  k1OverSqrt2, k1OverSqrt2, 0, 0,
517  -k1OverSqrt2, k1OverSqrt2, 0, 0,
518  0, 0, 1, 0,
519  0, 0, 1, 1,
520  };
521  // clang-format on
522  ASSERT_MATRIX_NEAR(m, expected);
523  }
524 
525  // Half way between +x and -y, yaw 90
526  {
527  auto m =
528  Matrix::MakeLookAt(Vector3(), Vector3(10, -10, 0), Vector3(0, 0, -1));
529 
530  // clang-format off
531  auto expected = Matrix{
532  -k1OverSqrt2, 0, k1OverSqrt2, 0,
533  -k1OverSqrt2, 0, -k1OverSqrt2, 0,
534  0, -1, 0, 0,
535  0, 0, 0, 1,
536  };
537  // clang-format on
538  ASSERT_MATRIX_NEAR(m, expected);
539  }
540 }

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

◆ TEST() [137/360]

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

Definition at line 375 of file geometry_unittests.cc.

375  {
376  {
377  auto m = Matrix::MakeOrthographic(Size(100, 200));
378  auto expect = Matrix{
379  0.02, 0, 0, 0, //
380  0, -0.01, 0, 0, //
381  0, 0, 0, 0, //
382  -1, 1, 0.5, 1, //
383  };
384  ASSERT_MATRIX_NEAR(m, expect);
385  }
386 
387  {
388  auto m = Matrix::MakeOrthographic(Size(400, 100));
389  auto expect = Matrix{
390  0.005, 0, 0, 0, //
391  0, -0.02, 0, 0, //
392  0, 0, 0, 0, //
393  -1, 1, 0.5, 1, //
394  };
395  ASSERT_MATRIX_NEAR(m, expect);
396  }
397 }

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

◆ TEST() [138/360]

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

Definition at line 399 of file geometry_unittests.cc.

399  {
400  {
401  auto m = Matrix::MakePerspective(Degrees(60), Size(100, 200), 1, 10);
402  auto expect = Matrix{
403  3.4641, 0, 0, 0, //
404  0, 1.73205, 0, 0, //
405  0, 0, 1.11111, 1, //
406  0, 0, -1.11111, 0, //
407  };
408  ASSERT_MATRIX_NEAR(m, expect);
409  }
410 
411  {
412  auto m = Matrix::MakePerspective(Radians(1), 2, 10, 20);
413  auto expect = Matrix{
414  0.915244, 0, 0, 0, //
415  0, 1.83049, 0, 0, //
416  0, 0, 2, 1, //
417  0, 0, -20, 0, //
418  };
419  ASSERT_MATRIX_NEAR(m, expect);
420  }
421 }

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

◆ TEST() [139/360]

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

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

Definition at line 1695 of file geometry_unittests.cc.

1695  {
1696  {
1697  std::stringstream stream;
1698  Matrix m;
1699  stream << m;
1700  ASSERT_EQ(stream.str(), R"((
1701  1.000000, 0.000000, 0.000000, 0.000000,
1702  0.000000, 1.000000, 0.000000, 0.000000,
1703  0.000000, 0.000000, 1.000000, 0.000000,
1704  0.000000, 0.000000, 0.000000, 1.000000,
1705 ))");
1706  }
1707 
1708  {
1709  std::stringstream stream;
1710  Matrix m = Matrix::MakeTranslation(Vector3(10, 20, 30));
1711  stream << m;
1712 
1713  ASSERT_EQ(stream.str(), R"((
1714  1.000000, 0.000000, 0.000000, 10.000000,
1715  0.000000, 1.000000, 0.000000, 20.000000,
1716  0.000000, 0.000000, 1.000000, 30.000000,
1717  0.000000, 0.000000, 0.000000, 1.000000,
1718 ))");
1719  }
1720 }

References impeller::Matrix::MakeTranslation().

◆ TEST() [141/360]

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 }

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

◆ TEST() [142/360]

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

Definition at line 470 of file geometry_unittests.cc.

470  {
471  {
472  auto m = Matrix();
473  bool result = m.IsTranslationScaleOnly();
474  ASSERT_TRUE(result);
475  }
476 
477  {
478  auto m = Matrix::MakeScale(Vector3(2, 3, 4));
479  bool result = m.IsTranslationScaleOnly();
480  ASSERT_TRUE(result);
481  }
482 
483  {
484  auto m = Matrix::MakeTranslation(Vector3(2, 3, 4));
485  bool result = m.IsTranslationScaleOnly();
486  ASSERT_TRUE(result);
487  }
488 
489  {
490  auto m = Matrix::MakeRotationZ(Degrees(10));
491  bool result = m.IsTranslationScaleOnly();
492  ASSERT_FALSE(result);
493  }
494 }

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

◆ TEST() [143/360]

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

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

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

Definition at line 953 of file geometry_unittests.cc.

953  {
954  Point a(-1, -2);
955  auto a_abs = a.Abs();
956  auto expected = Point(1, 2);
957  ASSERT_POINT_NEAR(a_abs, expected);
958 }

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

◆ TEST() [146/360]

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

Definition at line 990 of file geometry_unittests.cc.

990  {
991  // Negative result in the CCW (with up = -Y) direction.
992  {
993  Point a(1, 1);
994  Point b(1, -1);
995  Radians actual = a.AngleTo(b);
996  Radians expected = Radians{-kPi / 2};
997  ASSERT_FLOAT_EQ(actual.radians, expected.radians);
998  }
999 
1000  // Check the other direction to ensure the result is signed correctly.
1001  {
1002  Point a(1, -1);
1003  Point b(1, 1);
1004  Radians actual = a.AngleTo(b);
1005  Radians expected = Radians{kPi / 2};
1006  ASSERT_FLOAT_EQ(actual.radians, expected.radians);
1007  }
1008 
1009  // Differences in magnitude should have no impact on the result.
1010  {
1011  Point a(100, -100);
1012  Point b(0.01, 0.01);
1013  Radians actual = a.AngleTo(b);
1014  Radians expected = Radians{kPi / 2};
1015  ASSERT_FLOAT_EQ(actual.radians, expected.radians);
1016  }
1017 }

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

◆ TEST() [147/360]

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

Definition at line 1082 of file geometry_unittests.cc.

1082  {
1083  Point p(1.5, 2.3);
1084  Point result = p.Ceil();
1085  Point expected(2, 3);
1086  ASSERT_POINT_NEAR(result, expected);
1087 }

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

◆ TEST() [148/360]

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

Definition at line 908 of file geometry_unittests.cc.

908  {
909  {
910  Point p(1, 0);
911  Scalar s = p.Cross(Point(-1, 0));
912  ASSERT_FLOAT_EQ(s, 0);
913  }
914 
915  {
916  Point p(0, -1);
917  Scalar s = p.Cross(Point(-1, 0));
918  ASSERT_FLOAT_EQ(s, -1);
919  }
920 
921  {
922  Point p(1, 2);
923  Scalar s = p.Cross(Point(3, -4));
924  ASSERT_FLOAT_EQ(s, -10);
925  }
926 }

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

◆ TEST() [149/360]

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

Definition at line 888 of file geometry_unittests.cc.

888  {
889  {
890  Point p(1, 0);
891  Scalar s = p.Dot(Point(-1, 0));
892  ASSERT_FLOAT_EQ(s, -1);
893  }
894 
895  {
896  Point p(0, -1);
897  Scalar s = p.Dot(Point(-1, 0));
898  ASSERT_FLOAT_EQ(s, 0);
899  }
900 
901  {
902  Point p(1, 2);
903  Scalar s = p.Dot(Point(3, -4));
904  ASSERT_FLOAT_EQ(s, -5);
905  }
906 }

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

◆ TEST() [150/360]

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

Definition at line 1061 of file geometry_unittests.cc.

1061  {
1062  Point p(1.5, 2.3);
1063  Point result = p.Floor();
1064  Point expected(1, 2);
1065  ASSERT_POINT_NEAR(result, expected);
1066 }

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

◆ TEST() [151/360]

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

Definition at line 693 of file geometry_unittests.cc.

693  {
694  // Integer on LHS, float on RHS
695  {
696  IPoint p1(1, 2);
697  Point p2 = p1 + Point(1, 2);
698  ASSERT_FLOAT_EQ(p2.x, 2u);
699  ASSERT_FLOAT_EQ(p2.y, 4u);
700  }
701 
702  {
703  IPoint p1(3, 6);
704  Point p2 = p1 - Point(1, 2);
705  ASSERT_FLOAT_EQ(p2.x, 2u);
706  ASSERT_FLOAT_EQ(p2.y, 4u);
707  }
708 
709  {
710  IPoint p1(1, 2);
711  Point p2 = p1 * Point(2, 3);
712  ASSERT_FLOAT_EQ(p2.x, 2u);
713  ASSERT_FLOAT_EQ(p2.y, 6u);
714  }
715 
716  {
717  IPoint p1(2, 6);
718  Point p2 = p1 / Point(2, 3);
719  ASSERT_FLOAT_EQ(p2.x, 1u);
720  ASSERT_FLOAT_EQ(p2.y, 2u);
721  }
722 
723  // Float on LHS, integer on RHS
724  {
725  Point p1(1, 2);
726  Point p2 = p1 + IPoint(1, 2);
727  ASSERT_FLOAT_EQ(p2.x, 2u);
728  ASSERT_FLOAT_EQ(p2.y, 4u);
729  }
730 
731  {
732  Point p1(3, 6);
733  Point p2 = p1 - IPoint(1, 2);
734  ASSERT_FLOAT_EQ(p2.x, 2u);
735  ASSERT_FLOAT_EQ(p2.y, 4u);
736  }
737 
738  {
739  Point p1(1, 2);
740  Point p2 = p1 * IPoint(2, 3);
741  ASSERT_FLOAT_EQ(p2.x, 2u);
742  ASSERT_FLOAT_EQ(p2.y, 6u);
743  }
744 
745  {
746  Point p1(2, 6);
747  Point p2 = p1 / IPoint(2, 3);
748  ASSERT_FLOAT_EQ(p2.x, 1u);
749  ASSERT_FLOAT_EQ(p2.y, 2u);
750  }
751 }

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

◆ TEST() [152/360]

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

Definition at line 1124 of file geometry_unittests.cc.

1124  {
1125  Point p(1, 2);
1126  Point result = p.Lerp({5, 10}, 0.75);
1127  Point expected(4, 8);
1128  ASSERT_POINT_NEAR(result, expected);
1129 }

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

◆ TEST() [153/360]

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

Definition at line 1040 of file geometry_unittests.cc.

1040  {
1041  Point p(1, 2);
1042  Point result = p.Max({0, 10});
1043  Point expected(1, 10);
1044  ASSERT_POINT_NEAR(result, expected);
1045 }

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

◆ TEST() [154/360]

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

Definition at line 1019 of file geometry_unittests.cc.

1019  {
1020  Point p(1, 2);
1021  Point result = p.Min({0, 10});
1022  Point expected(0, 2);
1023  ASSERT_POINT_NEAR(result, expected);
1024 }

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

◆ TEST() [155/360]

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

Definition at line 1722 of file geometry_unittests.cc.

1722  {
1723  {
1724  std::stringstream stream;
1725  Point m;
1726  stream << m;
1727  ASSERT_EQ(stream.str(), "(0, 0)");
1728  }
1729 
1730  {
1731  std::stringstream stream;
1732  Point m(13, 37);
1733  stream << m;
1734  ASSERT_EQ(stream.str(), "(13, 37)");
1735  }
1736 }

◆ TEST() [156/360]

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

Definition at line 928 of file geometry_unittests.cc.

928  {
929  {
930  Point axis = Point(0, 1);
931  Point a(2, 3);
932  auto reflected = a.Reflect(axis);
933  auto expected = Point(2, -3);
934  ASSERT_POINT_NEAR(reflected, expected);
935  }
936 
937  {
938  Point axis = Point(1, 1).Normalize();
939  Point a(1, 0);
940  auto reflected = a.Reflect(axis);
941  auto expected = Point(0, -1);
942  ASSERT_POINT_NEAR(reflected, expected);
943  }
944 
945  {
946  Point axis = Point(1, 1).Normalize();
947  Point a(-1, -1);
948  auto reflected = a.Reflect(axis);
949  ASSERT_POINT_NEAR(reflected, -a);
950  }
951 }

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

◆ TEST() [157/360]

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

Definition at line 960 of file geometry_unittests.cc.

960  {
961  {
962  Point a(1, 0);
963  auto rotated = a.Rotate(Radians{kPiOver2});
964  auto expected = Point(0, 1);
965  ASSERT_POINT_NEAR(rotated, expected);
966  }
967 
968  {
969  Point a(1, 0);
970  auto rotated = a.Rotate(Radians{-kPiOver2});
971  auto expected = Point(0, -1);
972  ASSERT_POINT_NEAR(rotated, expected);
973  }
974 
975  {
976  Point a(1, 0);
977  auto rotated = a.Rotate(Radians{kPi});
978  auto expected = Point(-1, 0);
979  ASSERT_POINT_NEAR(rotated, expected);
980  }
981 
982  {
983  Point a(1, 0);
984  auto rotated = a.Rotate(Radians{kPi * 1.5});
985  auto expected = Point(0, -1);
986  ASSERT_POINT_NEAR(rotated, expected);
987  }
988 }

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

◆ TEST() [158/360]

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

Definition at line 1103 of file geometry_unittests.cc.

1103  {
1104  Point p(1.5, 2.3);
1105  Point result = p.Round();
1106  Point expected(2, 2);
1107  ASSERT_POINT_NEAR(result, expected);
1108 }

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

◆ TEST() [159/360]

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

Definition at line 542 of file geometry_unittests.cc.

542  {
543  auto q1 = Quaternion{{0.0, 0.0, 1.0}, 0.0};
544  auto q2 = Quaternion{{0.0, 0.0, 1.0}, kPiOver4};
545 
546  auto q3 = q1.Slerp(q2, 0.5);
547 
548  auto expected = Quaternion{{0.0, 0.0, 1.0}, kPiOver4 / 2.0};
549 
550  ASSERT_QUATERNION_NEAR(q3, expected);
551 }

References ASSERT_QUATERNION_NEAR, and impeller::kPiOver4.

◆ TEST() [160/360]

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

Definition at line 553 of file geometry_unittests.cc.

553  {
554  {
555  Quaternion q({0, 0, 1}, 0);
556  Vector3 v(0, 1, 0);
557 
558  Vector3 result = q * v;
559  Vector3 expected(0, 1, 0);
560 
561  ASSERT_VECTOR3_NEAR(result, expected);
562  }
563 
564  {
565  Quaternion q({0, 0, 1}, k2Pi);
566  Vector3 v(1, 0, 0);
567 
568  Vector3 result = q * v;
569  Vector3 expected(1, 0, 0);
570 
571  ASSERT_VECTOR3_NEAR(result, expected);
572  }
573 
574  {
575  Quaternion q({0, 0, 1}, kPiOver4);
576  Vector3 v(0, 1, 0);
577 
578  Vector3 result = q * v;
579  Vector3 expected(-k1OverSqrt2, k1OverSqrt2, 0);
580 
581  ASSERT_VECTOR3_NEAR(result, expected);
582  }
583 
584  {
585  Quaternion q(Vector3(1, 0, 1).Normalize(), kPi);
586  Vector3 v(0, 0, -1);
587 
588  Vector3 result = q * v;
589  Vector3 expected(-1, 0, 0);
590 
591  ASSERT_VECTOR3_NEAR(result, expected);
592  }
593 }

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

◆ TEST() [161/360]

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

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 }

References impeller::ScalarNearlyEqual().

◆ TEST() [163/360]

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

Definition at line 1179 of file geometry_unittests.cc.

1179  {
1180  {
1181  SeparatedVector2 v(Vector2(10, 0));
1182  Radians actual = v.AngleTo(SeparatedVector2(Vector2(5, 0)));
1183  Radians expected = Radians{0};
1184  ASSERT_NEAR(actual.radians, expected.radians, kEhCloseEnough);
1185  }
1186 
1187  {
1188  SeparatedVector2 v(Vector2(10, 0));
1189  Radians actual = v.AngleTo(SeparatedVector2(Vector2(0, -5)));
1190  Radians expected = Radians{-kPi / 2};
1191  ASSERT_NEAR(actual.radians, expected.radians, kEhCloseEnough);
1192  }
1193 }

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

◆ TEST() [164/360]

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

Definition at line 1156 of file geometry_unittests.cc.

1156  {
1157  // Parallel
1158  {
1159  SeparatedVector2 v(Vector2(10, 0));
1160  Scalar actual = v.GetAlignment(SeparatedVector2(Vector2(5, 0)));
1161  ASSERT_NEAR(actual, 1, kEhCloseEnough);
1162  }
1163 
1164  // Perpendicular
1165  {
1166  SeparatedVector2 v(Vector2(10, 0));
1167  Scalar actual = v.GetAlignment(SeparatedVector2(Vector2(0, 5)));
1168  ASSERT_NEAR(actual, 0, kEhCloseEnough);
1169  }
1170 
1171  // Opposite parallel
1172  {
1173  SeparatedVector2 v(Vector2(0, 10));
1174  Scalar actual = v.GetAlignment(SeparatedVector2(Vector2(0, -5)));
1175  ASSERT_NEAR(actual, -1, kEhCloseEnough);
1176  }
1177 }

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

◆ TEST() [165/360]

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

Definition at line 1151 of file geometry_unittests.cc.

1151  {
1152  SeparatedVector2 v(Vector2(10, 0));
1153  ASSERT_POINT_NEAR(v.GetVector(), Vector2(10, 0));
1154 }

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

◆ TEST() [166/360]

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

Definition at line 1145 of file geometry_unittests.cc.

1145  {
1146  SeparatedVector2 v(Vector2(10, 0));
1147  ASSERT_POINT_NEAR(v.direction, Vector2(1, 0));
1148  ASSERT_NEAR(v.magnitude, 10, kEhCloseEnough);
1149 }

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

◆ TEST() [167/360]

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

Definition at line 753 of file geometry_unittests.cc.

753  {
754  // Point on LHS, Size on RHS
755  {
756  IPoint p1(1, 2);
757  IPoint p2 = p1 + ISize(1, 2);
758  ASSERT_EQ(p2.x, 2u);
759  ASSERT_EQ(p2.y, 4u);
760  }
761 
762  {
763  IPoint p1(3, 6);
764  IPoint p2 = p1 - ISize(1, 2);
765  ASSERT_EQ(p2.x, 2u);
766  ASSERT_EQ(p2.y, 4u);
767  }
768 
769  {
770  IPoint p1(1, 2);
771  IPoint p2 = p1 * ISize(2, 3);
772  ASSERT_EQ(p2.x, 2u);
773  ASSERT_EQ(p2.y, 6u);
774  }
775 
776  {
777  IPoint p1(2, 6);
778  IPoint p2 = p1 / ISize(2, 3);
779  ASSERT_EQ(p2.x, 1u);
780  ASSERT_EQ(p2.y, 2u);
781  }
782 
783  // Size on LHS, Point on RHS
784  {
785  ISize p1(1, 2);
786  IPoint p2 = p1 + IPoint(1, 2);
787  ASSERT_EQ(p2.x, 2u);
788  ASSERT_EQ(p2.y, 4u);
789  }
790 
791  {
792  ISize p1(3, 6);
793  IPoint p2 = p1 - IPoint(1, 2);
794  ASSERT_EQ(p2.x, 2u);
795  ASSERT_EQ(p2.y, 4u);
796  }
797 
798  {
799  ISize p1(1, 2);
800  IPoint p2 = p1 * IPoint(2, 3);
801  ASSERT_EQ(p2.x, 2u);
802  ASSERT_EQ(p2.y, 6u);
803  }
804 
805  {
806  ISize p1(2, 6);
807  IPoint p2 = p1 / IPoint(2, 3);
808  ASSERT_EQ(p2.x, 1u);
809  ASSERT_EQ(p2.y, 2u);
810  }
811 }

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

◆ TEST() [168/360]

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

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

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

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

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

Definition at line 1786 of file geometry_unittests.cc.

1786  {
1787  ASSERT_EQ(Color::ToIColor(Color(0, 0, 0, 0)), 0u);
1788  ASSERT_EQ(Color::ToIColor(Color(1.0, 1.0, 1.0, 1.0)), 0xFFFFFFFF);
1789  ASSERT_EQ(Color::ToIColor(Color(0.5, 0.5, 1.0, 1.0)), 0xFF8080FF);
1790 }

References impeller::Color::ToIColor().

◆ TEST() [173/360]

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

Definition at line 1089 of file geometry_unittests.cc.

1089  {
1090  Vector3 p(1.5, 2.3, 3.9);
1091  Vector3 result = p.Ceil();
1092  Vector3 expected(2, 3, 4);
1093  ASSERT_VECTOR3_NEAR(result, expected);
1094 }

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

◆ TEST() [174/360]

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

Definition at line 1068 of file geometry_unittests.cc.

1068  {
1069  Vector3 p(1.5, 2.3, 3.9);
1070  Vector3 result = p.Floor();
1071  Vector3 expected(1, 2, 3);
1072  ASSERT_VECTOR3_NEAR(result, expected);
1073 }

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

◆ TEST() [175/360]

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

Definition at line 1131 of file geometry_unittests.cc.

1131  {
1132  Vector3 p(1, 2, 3);
1133  Vector3 result = p.Lerp({5, 10, 15}, 0.75);
1134  Vector3 expected(4, 8, 12);
1135  ASSERT_VECTOR3_NEAR(result, expected);
1136 }

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

◆ TEST() [176/360]

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

Definition at line 1047 of file geometry_unittests.cc.

1047  {
1048  Vector3 p(1, 2, 3);
1049  Vector3 result = p.Max({0, 10, 2});
1050  Vector3 expected(1, 10, 3);
1051  ASSERT_VECTOR3_NEAR(result, expected);
1052 }

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

◆ TEST() [177/360]

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

Definition at line 1026 of file geometry_unittests.cc.

1026  {
1027  Vector3 p(1, 2, 3);
1028  Vector3 result = p.Min({0, 10, 2});
1029  Vector3 expected(0, 2, 2);
1030  ASSERT_VECTOR3_NEAR(result, expected);
1031 }

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

◆ TEST() [178/360]

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

Definition at line 1738 of file geometry_unittests.cc.

1738  {
1739  {
1740  std::stringstream stream;
1741  Vector3 m;
1742  stream << m;
1743  ASSERT_EQ(stream.str(), "(0, 0, 0)");
1744  }
1745 
1746  {
1747  std::stringstream stream;
1748  Vector3 m(1, 2, 3);
1749  stream << m;
1750  ASSERT_EQ(stream.str(), "(1, 2, 3)");
1751  }
1752 }

◆ TEST() [179/360]

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

Definition at line 1110 of file geometry_unittests.cc.

1110  {
1111  Vector3 p(1.5, 2.3, 3.9);
1112  Vector3 result = p.Round();
1113  Vector3 expected(2, 2, 4);
1114  ASSERT_VECTOR3_NEAR(result, expected);
1115 }

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

◆ TEST() [180/360]

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

Definition at line 1096 of file geometry_unittests.cc.

1096  {
1097  Vector4 p(1.5, 2.3, 3.9, 4.0);
1098  Vector4 result = p.Ceil();
1099  Vector4 expected(2, 3, 4, 4);
1100  ASSERT_VECTOR4_NEAR(result, expected);
1101 }

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

◆ TEST() [181/360]

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

Definition at line 1075 of file geometry_unittests.cc.

1075  {
1076  Vector4 p(1.5, 2.3, 3.9, 4.0);
1077  Vector4 result = p.Floor();
1078  Vector4 expected(1, 2, 3, 4);
1079  ASSERT_VECTOR4_NEAR(result, expected);
1080 }

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

◆ TEST() [182/360]

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

Definition at line 1138 of file geometry_unittests.cc.

1138  {
1139  Vector4 p(1, 2, 3, 4);
1140  Vector4 result = p.Lerp({5, 10, 15, 20}, 0.75);
1141  Vector4 expected(4, 8, 12, 16);
1142  ASSERT_VECTOR4_NEAR(result, expected);
1143 }

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

◆ TEST() [183/360]

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

Definition at line 1054 of file geometry_unittests.cc.

1054  {
1055  Vector4 p(1, 2, 3, 4);
1056  Vector4 result = p.Max({0, 10, 2, 1});
1057  Vector4 expected(1, 10, 3, 4);
1058  ASSERT_VECTOR4_NEAR(result, expected);
1059 }

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

◆ TEST() [184/360]

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

Definition at line 1033 of file geometry_unittests.cc.

1033  {
1034  Vector4 p(1, 2, 3, 4);
1035  Vector4 result = p.Min({0, 10, 2, 1});
1036  Vector4 expected(0, 2, 2, 1);
1037  ASSERT_VECTOR4_NEAR(result, expected);
1038 }

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

◆ TEST() [185/360]

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

Definition at line 1754 of file geometry_unittests.cc.

1754  {
1755  {
1756  std::stringstream stream;
1757  Vector4 m;
1758  stream << m;
1759  ASSERT_EQ(stream.str(), "(0, 0, 0, 1)");
1760  }
1761 
1762  {
1763  std::stringstream stream;
1764  Vector4 m(1, 2, 3, 4);
1765  stream << m;
1766  ASSERT_EQ(stream.str(), "(1, 2, 3, 4)");
1767  }
1768 }

◆ TEST() [186/360]

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

Definition at line 1117 of file geometry_unittests.cc.

1117  {
1118  Vector4 p(1.5, 2.3, 3.9, 4.0);
1119  Vector4 result = p.Round();
1120  Vector4 expected(2, 2, 4, 4);
1121  ASSERT_VECTOR4_NEAR(result, expected);
1122 }

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

◆ TEST() [187/360]

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

Definition at line 70 of file matrix_filter_contents_unittests.cc.

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

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

◆ TEST() [188/360]

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

Definition at line 82 of file matrix_filter_contents_unittests.cc.

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

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

◆ TEST() [189/360]

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

Definition at line 50 of file matrix_filter_contents_unittests.cc.

50  {
51  MatrixFilterContents contents;
52  FilterInput::Vector inputs = {};
53  Entity entity;
54  std::optional<Rect> coverage =
55  contents.GetFilterCoverage(inputs, entity, /*effect_transform=*/Matrix());
56  ASSERT_FALSE(coverage.has_value());
57 }

References impeller::MatrixFilterContents::GetFilterCoverage().

◆ TEST() [190/360]

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

Definition at line 59 of file matrix_filter_contents_unittests.cc.

59  {
60  MatrixFilterContents contents;
61  FilterInput::Vector inputs = {
62  FilterInput::Make(Rect::MakeLTRB(10, 10, 110, 110))};
63  Entity entity;
64  std::optional<Rect> coverage =
65  contents.GetFilterCoverage(inputs, entity, /*effect_transform=*/Matrix());
66 
67  ASSERT_EQ(coverage, Rect::MakeLTRB(10, 10, 110, 110));
68 }

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

◆ TEST() [191/360]

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

Definition at line 45 of file matrix_filter_contents_unittests.cc.

45  {
46  MatrixFilterContents contents;
47  EXPECT_TRUE(contents.IsTranslationOnly());
48 }

References impeller::MatrixFilterContents::IsTranslationOnly().

◆ TEST() [192/360]

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

Definition at line 45 of file matrix_unittests.cc.

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

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

◆ TEST() [193/360]

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

Definition at line 27 of file matrix_unittests.cc.

27  {
28  EXPECT_FALSE(Matrix().HasPerspective2D());
29 
30  auto test = [](int index, bool expect) {
31  Matrix matrix;
32  EXPECT_FALSE(matrix.HasPerspective2D());
33  matrix.m[index] = 0.5f;
34  EXPECT_EQ(matrix.HasPerspective2D(), expect) << "index: " << index;
35  };
36 
37  // clang-format off
38  test( 0, false); test( 1, false); test( 2, false); test( 3, true);
39  test( 4, false); test( 5, false); test( 6, false); test( 7, true);
40  test( 8, false); test( 9, false); test(10, false); test(11, false);
41  test(12, false); test(13, false); test(14, false); test(15, true);
42  // clang-format on
43 }

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

◆ TEST() [194/360]

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

Definition at line 63 of file matrix_unittests.cc.

63  {
64  EXPECT_TRUE(Matrix::MakeTranslation({100, 100, 0}).HasTranslation());
65  EXPECT_TRUE(Matrix::MakeTranslation({0, 100, 0}).HasTranslation());
66  EXPECT_TRUE(Matrix::MakeTranslation({100, 0, 0}).HasTranslation());
67  EXPECT_FALSE(Matrix().HasTranslation());
68 }

References impeller::Matrix::MakeTranslation().

◆ TEST() [195/360]

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

Definition at line 103 of file matrix_unittests.cc.

103  {
104  EXPECT_TRUE(Matrix().IsAligned());
105  EXPECT_TRUE(Matrix::MakeScale({1.0f, 1.0f, 2.0f}).IsAligned());
106 
107  // Begin Legacy tests transferred over from geometry_unittests.cc
108  {
109  auto m = Matrix::MakeTranslation({1, 2, 3});
110  bool result = m.IsAligned();
111  ASSERT_TRUE(result);
112  }
113 
114  {
115  auto m = Matrix::MakeRotationZ(Degrees{123});
116  bool result = m.IsAligned();
117  ASSERT_FALSE(result);
118  }
119  // End Legacy tests transferred over from geometry_unittests.cc
120 
121  auto test = [](int index, bool expect) {
122  Matrix matrix;
123  EXPECT_TRUE(matrix.IsAligned());
124  matrix.m[index] = 0.5f;
125  EXPECT_EQ(matrix.IsAligned(), expect) << "index: " << index;
126  };
127 
128  // clang-format off
129  test( 0, true); test( 1, false); test( 2, false); test( 3, false);
130  test( 4, false); test( 5, true); test( 6, false); test( 7, false);
131  test( 8, false); test( 9, false); test(10, true); test(11, false);
132  test(12, true); test(13, true); test(14, true); test(15, false);
133  // clang-format on
134 
135  // True for quadrant rotations from -250 to +250 full circles
136  for (int i = -1000; i < 1000; i++) {
137  Degrees d = Degrees(i * 90);
138  Matrix matrix = Matrix::MakeRotationZ(Degrees(d));
139  EXPECT_TRUE(matrix.IsAligned()) << "degrees: " << d.degrees;
140  }
141 
142  // False for half degree rotations from -999.5 to +1000.5 degrees
143  for (int i = -1000; i < 1000; i++) {
144  Degrees d = Degrees(i + 0.5f);
145  Matrix matrix = Matrix::MakeRotationZ(Degrees(d));
146  EXPECT_FALSE(matrix.IsAligned()) << "degrees: " << d.degrees;
147  }
148 }

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

◆ TEST() [196/360]

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

Definition at line 70 of file matrix_unittests.cc.

70  {
71  EXPECT_TRUE(Matrix().IsAligned2D());
72  EXPECT_TRUE(Matrix::MakeScale({1.0f, 1.0f, 2.0f}).IsAligned2D());
73 
74  auto test = [](int index, bool expect) {
75  Matrix matrix;
76  EXPECT_TRUE(matrix.IsAligned2D());
77  matrix.m[index] = 0.5f;
78  EXPECT_EQ(matrix.IsAligned2D(), expect) << "index: " << index;
79  };
80 
81  // clang-format off
82  test( 0, true); test( 1, false); test( 2, true); test( 3, false);
83  test( 4, false); test( 5, true); test( 6, true); test( 7, false);
84  test( 8, true); test( 9, true); test(10, true); test(11, true);
85  test(12, true); test(13, true); test(14, true); test(15, false);
86  // clang-format on
87 
88  // True for quadrant rotations from -250 to +250 full circles
89  for (int i = -1000; i < 1000; i++) {
90  Degrees d = Degrees(i * 90);
91  Matrix matrix = Matrix::MakeRotationZ(Degrees(d));
92  EXPECT_TRUE(matrix.IsAligned2D()) << "degrees: " << d.degrees;
93  }
94 
95  // False for half degree rotations from -999.5 to +1000.5 degrees
96  for (int i = -1000; i < 1000; i++) {
97  Degrees d = Degrees(i + 0.5f);
98  Matrix matrix = Matrix::MakeRotationZ(Degrees(d));
99  EXPECT_FALSE(matrix.IsAligned2D()) << "degrees: " << d.degrees;
100  }
101 }

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

◆ TEST() [197/360]

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

Definition at line 14 of file matrix_unittests.cc.

14  {
15  Matrix x(0.0, 0.0, 0.0, 1.0, //
16  1.0, 0.0, 0.0, 1.0, //
17  0.0, 1.0, 0.0, 1.0, //
18  1.0, 1.0, 0.0, 1.0);
19  Matrix translate = Matrix::MakeTranslation({10, 20, 0});
20  Matrix result = translate * x;
21  EXPECT_TRUE(MatrixNear(result, Matrix(10.0, 20.0, 0.0, 1.0, //
22  11.0, 20.0, 0.0, 1.0, //
23  10.0, 21.0, 0.0, 1.0, //
24  11.0, 21.0, 0.0, 1.0)));
25 }

References impeller::Matrix::MakeTranslation(), and MatrixNear().

◆ TEST() [198/360]

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

Definition at line 150 of file matrix_unittests.cc.

150  {
151  Matrix matrix = Matrix::MakeColumn(
152  // clang-format off
153  2.0f, 3.0f, 5.0f, 7.0f,
154  11.0f, 13.0f, 17.0f, 19.0f,
155  23.0f, 29.0f, 31.0f, 37.0f,
156  41.0f, 43.0f, 47.0f, 53.0f
157  // clang-format on
158  );
159  EXPECT_EQ(matrix.TransformHomogenous({1.0f, -1.0f}),
160  Vector3(32.0f, 33.0f, 41.0f));
161 }

References impeller::Matrix::MakeColumn(), and impeller::Matrix::TransformHomogenous().

◆ TEST() [199/360]

impeller::testing::TEST ( PathTest  ,
BoundingBoxCubic   
)

Definition at line 339 of file path_unittests.cc.

339  {
340  PathBuilder builder;
341  auto path =
342  builder.AddCubicCurve({120, 160}, {25, 200}, {220, 260}, {220, 40})
343  .TakePath();
344  auto box = path.GetBoundingBox();
345  Rect expected = Rect::MakeXYWH(93.9101, 40, 126.09, 158.862);
346  ASSERT_TRUE(box.has_value());
347  ASSERT_RECT_NEAR(box.value_or(Rect::MakeMaximum()), expected);
348 }

References impeller::PathBuilder::AddCubicCurve(), ASSERT_RECT_NEAR, impeller::TRect< Scalar >::MakeMaximum(), and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST() [200/360]

impeller::testing::TEST ( PathTest  ,
BoundingBoxOfCompositePathIsCorrect   
)

Definition at line 350 of file path_unittests.cc.

350  {
351  PathBuilder builder;
352  builder.AddRoundedRect(Rect::MakeXYWH(10, 10, 300, 300), {50, 50, 50, 50});
353  auto path = builder.TakePath();
354  auto actual = path.GetBoundingBox();
355  Rect expected = Rect::MakeXYWH(10, 10, 300, 300);
356 
357  ASSERT_TRUE(actual.has_value());
358  ASSERT_RECT_NEAR(actual.value_or(Rect::MakeMaximum()), expected);
359 }

References impeller::PathBuilder::AddRoundedRect(), ASSERT_RECT_NEAR, impeller::Path::GetBoundingBox(), impeller::TRect< Scalar >::MakeMaximum(), impeller::TRect< Scalar >::MakeXYWH(), and impeller::PathBuilder::TakePath().

◆ TEST() [201/360]

impeller::testing::TEST ( PathTest  ,
CanBeCloned   
)

Definition at line 501 of file path_unittests.cc.

501  {
502  PathBuilder builder;
503  builder.MoveTo({10, 10});
504  builder.LineTo({20, 20});
505  builder.SetBounds(Rect::MakeLTRB(0, 0, 100, 100));
506  builder.SetConvexity(Convexity::kConvex);
507 
508  auto path_a = builder.TakePath(FillType::kOdd);
509  // NOLINTNEXTLINE(performance-unnecessary-copy-initialization)
510  auto path_b = path_a;
511 
512  EXPECT_EQ(path_a.GetBoundingBox(), path_b.GetBoundingBox());
513  EXPECT_EQ(path_a.GetFillType(), path_b.GetFillType());
514  EXPECT_EQ(path_a.IsConvex(), path_b.IsConvex());
515 
516  auto poly_a = path_a.CreatePolyline(1.0);
517  auto poly_b = path_b.CreatePolyline(1.0);
518 
519  ASSERT_EQ(poly_a.points->size(), poly_b.points->size());
520  ASSERT_EQ(poly_a.contours.size(), poly_b.contours.size());
521 
522  for (auto i = 0u; i < poly_a.points->size(); i++) {
523  EXPECT_EQ((*poly_a.points)[i], (*poly_b.points)[i]);
524  }
525 
526  for (auto i = 0u; i < poly_a.contours.size(); i++) {
527  EXPECT_EQ(poly_a.contours[i].start_index, poly_b.contours[i].start_index);
528  EXPECT_EQ(poly_a.contours[i].start_direction,
529  poly_b.contours[i].start_direction);
530  }
531 }

References impeller::kConvex, impeller::kOdd, impeller::PathBuilder::LineTo(), impeller::TRect< Scalar >::MakeLTRB(), impeller::PathBuilder::MoveTo(), impeller::PathBuilder::SetBounds(), impeller::PathBuilder::SetConvexity(), and impeller::PathBuilder::TakePath().

◆ TEST() [202/360]

impeller::testing::TEST ( PathTest  ,
CloseAfterMoveDoesNotAddNewLines   
)

Definition at line 471 of file path_unittests.cc.

471  {
472  PathBuilder builder;
473  auto path = builder.LineTo({0, 10})
474  .LineTo({10, 10})
475  .MoveTo({30, 30}) // Moves to (30, 30)
476  .Close() // No Op
477  .Close() // Still No op
478  .TakePath();
479 
480  EXPECT_EQ(path.GetComponentCount(), 4u);
481  EXPECT_EQ(path.GetComponentCount(Path::ComponentType::kLinear), 2u);
482  EXPECT_EQ(path.GetComponentCount(Path::ComponentType::kContour), 2u);
483 }

References impeller::Close(), impeller::Path::kContour, impeller::Path::kLinear, impeller::LineTo(), impeller::PathBuilder::LineTo(), and impeller::MoveTo().

◆ TEST() [203/360]

impeller::testing::TEST ( PathTest  ,
CloseAtOriginDoesNotAddNewLineSegment   
)

Definition at line 485 of file path_unittests.cc.

485  {
486  PathBuilder builder;
487  // Create a path that has a current position at the origin when close is
488  // called. This should not insert a new line segment
489  auto path = builder.LineTo({10, 0})
490  .LineTo({10, 10})
491  .LineTo({0, 10})
492  .LineTo({0, 0})
493  .Close()
494  .TakePath();
495 
496  EXPECT_EQ(path.GetComponentCount(), 6u);
497  EXPECT_EQ(path.GetComponentCount(Path::ComponentType::kLinear), 4u);
498  EXPECT_EQ(path.GetComponentCount(Path::ComponentType::kContour), 2u);
499 }

References impeller::Close(), impeller::Path::kContour, impeller::Path::kLinear, impeller::LineTo(), and impeller::PathBuilder::LineTo().

◆ TEST() [204/360]

impeller::testing::TEST ( PathTest  ,
CubicPath   
)

Definition at line 324 of file path_unittests.cc.

324  {
325  PathBuilder builder;
326  auto path =
327  builder.CubicCurveTo(Point(10, 10), Point(-10, -10), Point(20, 20))
328  .TakePath();
329 
330  CubicPathComponent cubic;
331  path.GetCubicComponentAtIndex(1, cubic);
332 
333  EXPECT_EQ(cubic.p1, Point(0, 0));
334  EXPECT_EQ(cubic.cp1, Point(10, 10));
335  EXPECT_EQ(cubic.cp2, Point(-10, -10));
336  EXPECT_EQ(cubic.p2, Point(20, 20));
337 }

References impeller::CubicPathComponent::cp1, impeller::CubicPathComponent::cp2, impeller::PathBuilder::CubicCurveTo(), impeller::CubicPathComponent::p1, impeller::CubicPathComponent::p2, and impeller::PathBuilder::TakePath().

◆ TEST() [205/360]

impeller::testing::TEST ( PathTest  ,
CubicPathComponentPolylineDoesNotIncludePointOne   
)

Definition at line 15 of file path_unittests.cc.

15  {
16  CubicPathComponent component({10, 10}, {20, 35}, {35, 20}, {40, 40});
17  std::vector<Point> polyline;
18  component.AppendPolylinePoints(1.0f, polyline);
19  ASSERT_NE(polyline.front().x, 10);
20  ASSERT_NE(polyline.front().y, 10);
21  ASSERT_EQ(polyline.back().x, 40);
22  ASSERT_EQ(polyline.back().y, 40);
23 }

References polyline.

◆ TEST() [206/360]

impeller::testing::TEST ( PathTest  ,
EmptyPath   
)

Definition at line 384 of file path_unittests.cc.

384  {
385  auto path = PathBuilder{}.TakePath();
386  ASSERT_EQ(path.GetComponentCount(), 1u);
387 
388  ContourComponent c;
389  path.GetContourComponentAtIndex(0, c);
390  ASSERT_POINT_NEAR(c.destination, Point());
391 
392  Path::Polyline polyline = path.CreatePolyline(1.0f);
393  ASSERT_TRUE(polyline.points->empty());
394  ASSERT_TRUE(polyline.contours.empty());
395 }

References ASSERT_POINT_NEAR, impeller::ContourComponent::destination, polyline, and impeller::PathBuilder::TakePath().

◆ TEST() [207/360]

impeller::testing::TEST ( PathTest  ,
ExtremaOfCubicPathComponentIsCorrect   
)

Definition at line 361 of file path_unittests.cc.

361  {
362  CubicPathComponent cubic{{11.769268, 252.883148},
363  {-6.2857933, 204.356461},
364  {-4.53997231, 156.552902},
365  {17.0067291, 109.472488}};
366  auto points = cubic.Extrema();
367 
368  ASSERT_EQ(points.size(), static_cast<size_t>(3));
369  ASSERT_POINT_NEAR(points[2], cubic.Solve(0.455916));
370 }

References ASSERT_POINT_NEAR, and impeller::CubicPathComponent::Extrema().

◆ TEST() [208/360]

impeller::testing::TEST ( PathTest  ,
PathAddRectPolylineHasCorrectContourData   
)

Definition at line 160 of file path_unittests.cc.

160  {
161  Path::Polyline polyline = PathBuilder{}
162  .AddRect(Rect::MakeLTRB(50, 60, 70, 80))
163  .TakePath()
164  .CreatePolyline(1.0f);
165  ASSERT_EQ(polyline.contours.size(), 1u);
166  ASSERT_TRUE(polyline.contours[0].is_closed);
167  ASSERT_EQ(polyline.contours[0].start_index, 0u);
168  ASSERT_EQ(polyline.points->size(), 5u);
169  ASSERT_EQ(polyline.GetPoint(0), Point(50, 60));
170  ASSERT_EQ(polyline.GetPoint(1), Point(70, 60));
171  ASSERT_EQ(polyline.GetPoint(2), Point(70, 80));
172  ASSERT_EQ(polyline.GetPoint(3), Point(50, 80));
173  ASSERT_EQ(polyline.GetPoint(4), Point(50, 60));
174 }

References impeller::PathBuilder::AddRect(), impeller::Path::CreatePolyline(), impeller::TRect< Scalar >::MakeLTRB(), polyline, and impeller::PathBuilder::TakePath().

◆ TEST() [209/360]

impeller::testing::TEST ( PathTest  ,
PathBuilderDoesNotMutateCopiedPaths   
)

Definition at line 533 of file path_unittests.cc.

533  {
534  auto test_isolation =
535  [](const std::function<void(PathBuilder & builder)>& mutator,
536  bool will_close, Point mutation_offset, const std::string& label) {
537  PathBuilder builder;
538  builder.MoveTo({10, 10});
539  builder.LineTo({20, 20});
540  builder.LineTo({20, 10});
541 
542  auto verify_path = [](const Path& path, bool is_mutated, bool is_closed,
543  Point offset, const std::string& label) {
544  if (is_mutated) {
545  // We can only test the initial state before the mutator did
546  // its work. We have >= 3 components and the first 3 components
547  // will match what we saw before the mutation.
548  EXPECT_GE(path.GetComponentCount(), 3u) << label;
549  } else {
550  EXPECT_EQ(path.GetComponentCount(), 3u) << label;
551  }
552  {
553  ContourComponent contour;
554  EXPECT_TRUE(path.GetContourComponentAtIndex(0, contour)) << label;
555  EXPECT_EQ(contour.destination, offset + Point(10, 10)) << label;
556  EXPECT_EQ(contour.is_closed, is_closed) << label;
557  }
558  {
559  LinearPathComponent line;
560  EXPECT_TRUE(path.GetLinearComponentAtIndex(1, line)) << label;
561  EXPECT_EQ(line.p1, offset + Point(10, 10)) << label;
562  EXPECT_EQ(line.p2, offset + Point(20, 20)) << label;
563  }
564  {
565  LinearPathComponent line;
566  EXPECT_TRUE(path.GetLinearComponentAtIndex(2, line)) << label;
567  EXPECT_EQ(line.p1, offset + Point(20, 20)) << label;
568  EXPECT_EQ(line.p2, offset + Point(20, 10)) << label;
569  }
570  };
571 
572  auto path1 = builder.CopyPath();
573  verify_path(path1, false, false, {},
574  "Initial Path1 state before " + label);
575 
576  for (int i = 0; i < 10; i++) {
577  auto path = builder.CopyPath();
578  verify_path(
579  path, false, false, {},
580  "Extra CopyPath #" + std::to_string(i + 1) + " for " + label);
581  }
582  mutator(builder);
583  verify_path(path1, false, false, {},
584  "Path1 state after subsequent " + label);
585 
586  auto path2 = builder.CopyPath();
587  verify_path(path1, false, false, {},
588  "Path1 state after subsequent " + label + " and CopyPath");
589  verify_path(path2, true, will_close, mutation_offset,
590  "Initial Path2 state with subsequent " + label);
591  };
592 
593  test_isolation(
594  [](PathBuilder& builder) { //
595  builder.SetConvexity(Convexity::kConvex);
596  },
597  false, {}, "SetConvex");
598 
599  test_isolation(
600  [](PathBuilder& builder) { //
601  builder.SetConvexity(Convexity::kUnknown);
602  },
603  false, {}, "SetUnknownConvex");
604 
605  test_isolation(
606  [](PathBuilder& builder) { //
607  builder.Close();
608  },
609  true, {}, "Close");
610 
611  test_isolation(
612  [](PathBuilder& builder) {
613  builder.MoveTo({20, 30}, false);
614  },
615  false, {}, "Absolute MoveTo");
616 
617  test_isolation(
618  [](PathBuilder& builder) {
619  builder.MoveTo({20, 30}, true);
620  },
621  false, {}, "Relative MoveTo");
622 
623  test_isolation(
624  [](PathBuilder& builder) {
625  builder.LineTo({20, 30}, false);
626  },
627  false, {}, "Absolute LineTo");
628 
629  test_isolation(
630  [](PathBuilder& builder) {
631  builder.LineTo({20, 30}, true);
632  },
633  false, {}, "Relative LineTo");
634 
635  test_isolation(
636  [](PathBuilder& builder) { //
637  builder.HorizontalLineTo(100, false);
638  },
639  false, {}, "Absolute HorizontalLineTo");
640 
641  test_isolation(
642  [](PathBuilder& builder) { //
643  builder.HorizontalLineTo(100, true);
644  },
645  false, {}, "Relative HorizontalLineTo");
646 
647  test_isolation(
648  [](PathBuilder& builder) { //
649  builder.VerticalLineTo(100, false);
650  },
651  false, {}, "Absolute VerticalLineTo");
652 
653  test_isolation(
654  [](PathBuilder& builder) { //
655  builder.VerticalLineTo(100, true);
656  },
657  false, {}, "Relative VerticalLineTo");
658 
659  test_isolation(
660  [](PathBuilder& builder) {
661  builder.QuadraticCurveTo({20, 30}, {30, 20}, false);
662  },
663  false, {}, "Absolute QuadraticCurveTo");
664 
665  test_isolation(
666  [](PathBuilder& builder) {
667  builder.QuadraticCurveTo({20, 30}, {30, 20}, true);
668  },
669  false, {}, "Relative QuadraticCurveTo");
670 
671  test_isolation(
672  [](PathBuilder& builder) {
673  builder.CubicCurveTo({20, 30}, {30, 20}, {30, 30}, false);
674  },
675  false, {}, "Absolute CubicCurveTo");
676 
677  test_isolation(
678  [](PathBuilder& builder) {
679  builder.CubicCurveTo({20, 30}, {30, 20}, {30, 30}, true);
680  },
681  false, {}, "Relative CubicCurveTo");
682 
683  test_isolation(
684  [](PathBuilder& builder) {
685  builder.AddLine({100, 100}, {150, 100});
686  },
687  false, {}, "AddLine");
688 
689  test_isolation(
690  [](PathBuilder& builder) {
691  builder.AddRect(Rect::MakeLTRB(100, 100, 120, 120));
692  },
693  false, {}, "AddRect");
694 
695  test_isolation(
696  [](PathBuilder& builder) {
697  builder.AddOval(Rect::MakeLTRB(100, 100, 120, 120));
698  },
699  false, {}, "AddOval");
700 
701  test_isolation(
702  [](PathBuilder& builder) {
703  builder.AddCircle({100, 100}, 20);
704  },
705  false, {}, "AddCircle");
706 
707  test_isolation(
708  [](PathBuilder& builder) {
709  builder.AddArc(Rect::MakeLTRB(100, 100, 120, 120), Degrees(10),
710  Degrees(170));
711  },
712  false, {}, "AddArc");
713 
714  test_isolation(
715  [](PathBuilder& builder) {
716  builder.AddQuadraticCurve({100, 100}, {150, 100}, {150, 150});
717  },
718  false, {}, "AddQuadraticCurve");
719 
720  test_isolation(
721  [](PathBuilder& builder) {
722  builder.AddCubicCurve({100, 100}, {150, 100}, {100, 150}, {150, 150});
723  },
724  false, {}, "AddCubicCurve");
725 
726  test_isolation(
727  [](PathBuilder& builder) {
728  builder.Shift({23, 42});
729  },
730  false, {23, 42}, "Shift");
731 }

References impeller::PathBuilder::AddArc(), impeller::PathBuilder::AddCircle(), impeller::PathBuilder::AddCubicCurve(), impeller::PathBuilder::AddLine(), impeller::PathBuilder::AddOval(), impeller::PathBuilder::AddQuadraticCurve(), impeller::PathBuilder::AddRect(), impeller::PathBuilder::Close(), impeller::PathBuilder::CopyPath(), impeller::PathBuilder::CubicCurveTo(), impeller::ContourComponent::destination, impeller::Path::GetComponentCount(), impeller::Path::GetContourComponentAtIndex(), impeller::Path::GetLinearComponentAtIndex(), impeller::PathBuilder::HorizontalLineTo(), impeller::ContourComponent::is_closed, impeller::kConvex, impeller::kUnknown, impeller::PathBuilder::LineTo(), impeller::TRect< Scalar >::MakeLTRB(), impeller::PathBuilder::MoveTo(), offset, impeller::LinearPathComponent::p1, impeller::LinearPathComponent::p2, impeller::PathBuilder::QuadraticCurveTo(), impeller::PathBuilder::SetConvexity(), impeller::PathBuilder::Shift(), and impeller::PathBuilder::VerticalLineTo().

◆ TEST() [210/360]

impeller::testing::TEST ( PathTest  ,
PathBuilderSetsCorrectContourPropertiesForAddCommands   
)

Definition at line 44 of file path_unittests.cc.

44  {
45  // Closed shapes.
46  {
47  Path path = PathBuilder{}.AddCircle({100, 100}, 50).TakePath();
48  ContourComponent contour;
49  path.GetContourComponentAtIndex(0, contour);
50  EXPECT_POINT_NEAR(contour.destination, Point(100, 50));
51  EXPECT_TRUE(contour.is_closed);
52  }
53 
54  {
55  Path path =
56  PathBuilder{}.AddOval(Rect::MakeXYWH(100, 100, 100, 100)).TakePath();
57  ContourComponent contour;
58  path.GetContourComponentAtIndex(0, contour);
59  EXPECT_POINT_NEAR(contour.destination, Point(150, 100));
60  EXPECT_TRUE(contour.is_closed);
61  }
62 
63  {
64  Path path =
65  PathBuilder{}.AddRect(Rect::MakeXYWH(100, 100, 100, 100)).TakePath();
66  ContourComponent contour;
67  path.GetContourComponentAtIndex(0, contour);
68  EXPECT_POINT_NEAR(contour.destination, Point(100, 100));
69  EXPECT_TRUE(contour.is_closed);
70  }
71 
72  {
73  Path path = PathBuilder{}
74  .AddRoundedRect(Rect::MakeXYWH(100, 100, 100, 100), 10)
75  .TakePath();
76  ContourComponent contour;
77  path.GetContourComponentAtIndex(0, contour);
78  EXPECT_POINT_NEAR(contour.destination, Point(110, 100));
79  EXPECT_TRUE(contour.is_closed);
80  }
81 
82  {
83  Path path =
84  PathBuilder{}
85  .AddRoundedRect(Rect::MakeXYWH(100, 100, 100, 100), Size(10, 20))
86  .TakePath();
87  ContourComponent contour;
88  path.GetContourComponentAtIndex(0, contour);
89  EXPECT_POINT_NEAR(contour.destination, Point(110, 100));
90  EXPECT_TRUE(contour.is_closed);
91  }
92 
93  // Open shapes.
94  {
95  Point p(100, 100);
96  Path path = PathBuilder{}.AddLine(p, {200, 100}).TakePath();
97  ContourComponent contour;
98  path.GetContourComponentAtIndex(0, contour);
99  ASSERT_POINT_NEAR(contour.destination, p);
100  ASSERT_FALSE(contour.is_closed);
101  }
102 
103  {
104  Path path =
105  PathBuilder{}
106  .AddCubicCurve({100, 100}, {100, 50}, {100, 150}, {200, 100})
107  .TakePath();
108  ContourComponent contour;
109  path.GetContourComponentAtIndex(0, contour);
110  ASSERT_POINT_NEAR(contour.destination, Point(100, 100));
111  ASSERT_FALSE(contour.is_closed);
112  }
113 
114  {
115  Path path = PathBuilder{}
116  .AddQuadraticCurve({100, 100}, {100, 50}, {200, 100})
117  .TakePath();
118  ContourComponent contour;
119  path.GetContourComponentAtIndex(0, contour);
120  ASSERT_POINT_NEAR(contour.destination, Point(100, 100));
121  ASSERT_FALSE(contour.is_closed);
122  }
123 }

References impeller::PathBuilder::AddCircle(), impeller::PathBuilder::AddCubicCurve(), impeller::PathBuilder::AddLine(), impeller::PathBuilder::AddOval(), impeller::PathBuilder::AddQuadraticCurve(), impeller::PathBuilder::AddRect(), impeller::PathBuilder::AddRoundedRect(), ASSERT_POINT_NEAR, impeller::ContourComponent::destination, EXPECT_POINT_NEAR, impeller::Path::GetContourComponentAtIndex(), impeller::ContourComponent::is_closed, impeller::TRect< Scalar >::MakeXYWH(), and impeller::PathBuilder::TakePath().

◆ TEST() [211/360]

impeller::testing::TEST ( PathTest  ,
PathBuilderWillComputeBounds   
)

Definition at line 268 of file path_unittests.cc.

268  {
269  PathBuilder builder;
270  auto path_1 = builder.AddLine({0, 0}, {1, 1}).TakePath();
271 
272  ASSERT_EQ(path_1.GetBoundingBox().value_or(Rect::MakeMaximum()),
273  Rect::MakeLTRB(0, 0, 1, 1));
274 
275  auto path_2 = builder.AddLine({-1, -1}, {1, 1}).TakePath();
276 
277  // Verify that PathBuilder recomputes the bounds.
278  ASSERT_EQ(path_2.GetBoundingBox().value_or(Rect::MakeMaximum()),
279  Rect::MakeLTRB(-1, -1, 1, 1));
280 
281  // PathBuilder can set the bounds to whatever it wants
282  auto path_3 = builder.AddLine({0, 0}, {1, 1})
283  .SetBounds(Rect::MakeLTRB(0, 0, 100, 100))
284  .TakePath();
285 
286  ASSERT_EQ(path_3.GetBoundingBox().value_or(Rect::MakeMaximum()),
287  Rect::MakeLTRB(0, 0, 100, 100));
288 }

References impeller::PathBuilder::AddLine(), impeller::TRect< Scalar >::MakeLTRB(), impeller::TRect< Scalar >::MakeMaximum(), and impeller::PathBuilder::TakePath().

◆ TEST() [212/360]

impeller::testing::TEST ( PathTest  ,
PathCreatePolyLineDoesNotDuplicatePoints   
)

Definition at line 25 of file path_unittests.cc.

25  {
26  PathBuilder builder;
27  builder.MoveTo({10, 10});
28  builder.LineTo({20, 20});
29  builder.LineTo({30, 30});
30  builder.MoveTo({40, 40});
31  builder.LineTo({50, 50});
32 
33  auto polyline = builder.TakePath().CreatePolyline(1.0f);
34 
35  ASSERT_EQ(polyline.contours.size(), 2u);
36  ASSERT_EQ(polyline.points->size(), 5u);
37  ASSERT_EQ(polyline.GetPoint(0).x, 10);
38  ASSERT_EQ(polyline.GetPoint(1).x, 20);
39  ASSERT_EQ(polyline.GetPoint(2).x, 30);
40  ASSERT_EQ(polyline.GetPoint(3).x, 40);
41  ASSERT_EQ(polyline.GetPoint(4).x, 50);
42 }

References impeller::Path::CreatePolyline(), impeller::PathBuilder::LineTo(), impeller::PathBuilder::MoveTo(), polyline, and impeller::PathBuilder::TakePath().

◆ TEST() [213/360]

impeller::testing::TEST ( PathTest  ,
PathCreatePolylineGeneratesCorrectContourData   
)

Definition at line 125 of file path_unittests.cc.

125  {
126  Path::Polyline polyline = PathBuilder{}
127  .AddLine({100, 100}, {200, 100})
128  .MoveTo({100, 200})
129  .LineTo({150, 250})
130  .LineTo({200, 200})
131  .Close()
132  .TakePath()
133  .CreatePolyline(1.0f);
134  ASSERT_EQ(polyline.points->size(), 6u);
135  ASSERT_EQ(polyline.contours.size(), 2u);
136  ASSERT_EQ(polyline.contours[0].is_closed, false);
137  ASSERT_EQ(polyline.contours[0].start_index, 0u);
138  ASSERT_EQ(polyline.contours[1].is_closed, true);
139  ASSERT_EQ(polyline.contours[1].start_index, 2u);
140 }

References impeller::PathBuilder::AddLine(), impeller::Close(), impeller::LineTo(), impeller::MoveTo(), and polyline.

◆ TEST() [214/360]

impeller::testing::TEST ( PathTest  ,
PathGetBoundingBoxForCubicWithNoDerivativeRootsIsCorrect   
)

Definition at line 372 of file path_unittests.cc.

372  {
373  PathBuilder builder;
374  // Straight diagonal line.
375  builder.AddCubicCurve({0, 1}, {2, 3}, {4, 5}, {6, 7});
376  auto path = builder.TakePath();
377  auto actual = path.GetBoundingBox();
378  auto expected = Rect::MakeLTRB(0, 1, 6, 7);
379 
380  ASSERT_TRUE(actual.has_value());
381  ASSERT_RECT_NEAR(actual.value_or(Rect::MakeMaximum()), expected);
382 }

References impeller::PathBuilder::AddCubicCurve(), ASSERT_RECT_NEAR, impeller::Path::GetBoundingBox(), impeller::TRect< Scalar >::MakeLTRB(), impeller::TRect< Scalar >::MakeMaximum(), and impeller::PathBuilder::TakePath().

◆ TEST() [215/360]

impeller::testing::TEST ( PathTest  ,
PathHorizontalLine   
)

Definition at line 290 of file path_unittests.cc.

290  {
291  PathBuilder builder;
292  auto path = builder.HorizontalLineTo(10).TakePath();
293 
294  LinearPathComponent linear;
295  path.GetLinearComponentAtIndex(1, linear);
296 
297  EXPECT_EQ(linear.p1, Point(0, 0));
298  EXPECT_EQ(linear.p2, Point(10, 0));
299 }

References impeller::PathBuilder::HorizontalLineTo(), impeller::LinearPathComponent::p1, impeller::LinearPathComponent::p2, and impeller::PathBuilder::TakePath().

◆ TEST() [216/360]

impeller::testing::TEST ( PathTest  ,
PathPolylineDuplicatesAreRemovedForSameContour   
)

Definition at line 176 of file path_unittests.cc.

176  {
177  Path::Polyline polyline =
178  PathBuilder{}
179  .MoveTo({50, 50})
180  .LineTo({50, 50}) // Insert duplicate at beginning of contour.
181  .LineTo({100, 50})
182  .LineTo({100, 50}) // Insert duplicate at contour join.
183  .LineTo({100, 100})
184  .Close() // Implicitly insert duplicate {50, 50} across contours.
185  .LineTo({0, 50})
186  .LineTo({0, 100})
187  .LineTo({0, 100}) // Insert duplicate at end of contour.
188  .TakePath()
189  .CreatePolyline(1.0f);
190  ASSERT_EQ(polyline.contours.size(), 2u);
191  ASSERT_EQ(polyline.contours[0].start_index, 0u);
192  ASSERT_TRUE(polyline.contours[0].is_closed);
193  ASSERT_EQ(polyline.contours[1].start_index, 4u);
194  ASSERT_FALSE(polyline.contours[1].is_closed);
195  ASSERT_EQ(polyline.points->size(), 7u);
196  ASSERT_EQ(polyline.GetPoint(0), Point(50, 50));
197  ASSERT_EQ(polyline.GetPoint(1), Point(100, 50));
198  ASSERT_EQ(polyline.GetPoint(2), Point(100, 100));
199  ASSERT_EQ(polyline.GetPoint(3), Point(50, 50));
200  ASSERT_EQ(polyline.GetPoint(4), Point(50, 50));
201  ASSERT_EQ(polyline.GetPoint(5), Point(0, 50));
202  ASSERT_EQ(polyline.GetPoint(6), Point(0, 100));
203 }

References impeller::Close(), impeller::LineTo(), impeller::PathBuilder::MoveTo(), and polyline.

◆ TEST() [217/360]

impeller::testing::TEST ( PathTest  ,
PathShifting   
)

Definition at line 232 of file path_unittests.cc.

232  {
233  PathBuilder builder{};
234  auto path =
235  builder.AddLine(Point(0, 0), Point(10, 10))
236  .AddQuadraticCurve(Point(10, 10), Point(15, 15), Point(20, 20))
237  .AddCubicCurve(Point(20, 20), Point(25, 25), Point(-5, -5),
238  Point(30, 30))
239  .Close()
240  .Shift(Point(1, 1))
241  .TakePath();
242 
243  ContourComponent contour;
244  LinearPathComponent linear;
245  QuadraticPathComponent quad;
246  CubicPathComponent cubic;
247 
248  ASSERT_TRUE(path.GetContourComponentAtIndex(0, contour));
249  ASSERT_TRUE(path.GetLinearComponentAtIndex(1, linear));
250  ASSERT_TRUE(path.GetQuadraticComponentAtIndex(3, quad));
251  ASSERT_TRUE(path.GetCubicComponentAtIndex(5, cubic));
252 
253  EXPECT_EQ(contour.destination, Point(1, 1));
254 
255  EXPECT_EQ(linear.p1, Point(1, 1));
256  EXPECT_EQ(linear.p2, Point(11, 11));
257 
258  EXPECT_EQ(quad.cp, Point(16, 16));
259  EXPECT_EQ(quad.p1, Point(11, 11));
260  EXPECT_EQ(quad.p2, Point(21, 21));
261 
262  EXPECT_EQ(cubic.cp1, Point(26, 26));
263  EXPECT_EQ(cubic.cp2, Point(-4, -4));
264  EXPECT_EQ(cubic.p1, Point(21, 21));
265  EXPECT_EQ(cubic.p2, Point(31, 31));
266 }

References impeller::PathBuilder::AddCubicCurve(), impeller::PathBuilder::AddLine(), impeller::PathBuilder::AddQuadraticCurve(), impeller::PathBuilder::Close(), impeller::QuadraticPathComponent::cp, impeller::CubicPathComponent::cp1, impeller::CubicPathComponent::cp2, impeller::ContourComponent::destination, impeller::LinearPathComponent::p1, impeller::QuadraticPathComponent::p1, impeller::CubicPathComponent::p1, impeller::LinearPathComponent::p2, impeller::QuadraticPathComponent::p2, impeller::CubicPathComponent::p2, impeller::PathBuilder::Shift(), and impeller::PathBuilder::TakePath().

◆ TEST() [218/360]

impeller::testing::TEST ( PathTest  ,
PathVerticalLine   
)

Definition at line 301 of file path_unittests.cc.

301  {
302  PathBuilder builder;
303  auto path = builder.VerticalLineTo(10).TakePath();
304 
305  LinearPathComponent linear;
306  path.GetLinearComponentAtIndex(1, linear);
307 
308  EXPECT_EQ(linear.p1, Point(0, 0));
309  EXPECT_EQ(linear.p2, Point(0, 10));
310 }

References impeller::LinearPathComponent::p1, impeller::LinearPathComponent::p2, impeller::PathBuilder::TakePath(), and impeller::PathBuilder::VerticalLineTo().

◆ TEST() [219/360]

impeller::testing::TEST ( PathTest  ,
PolylineBufferReuse   
)

Definition at line 205 of file path_unittests.cc.

205  {
206  auto point_buffer = std::make_unique<std::vector<Point>>();
207  auto point_buffer_address = reinterpret_cast<uintptr_t>(point_buffer.get());
208  Path::Polyline polyline =
209  PathBuilder{}
210  .MoveTo({50, 50})
211  .LineTo({100, 100})
212  .TakePath()
213  .CreatePolyline(
214  1.0f, std::move(point_buffer),
215  [point_buffer_address](
216  Path::Polyline::PointBufferPtr point_buffer) {
217  ASSERT_EQ(point_buffer->size(), 0u);
218  ASSERT_EQ(point_buffer_address,
219  reinterpret_cast<uintptr_t>(point_buffer.get()));
220  });
221 }

References impeller::LineTo(), impeller::PathBuilder::MoveTo(), and polyline.

◆ TEST() [220/360]

impeller::testing::TEST ( PathTest  ,
PolylineFailsWithNullptrBuffer   
)

Definition at line 223 of file path_unittests.cc.

223  {
224  EXPECT_DEATH_IF_SUPPORTED(PathBuilder{}
225  .MoveTo({50, 50})
226  .LineTo({100, 100})
227  .TakePath()
228  .CreatePolyline(1.0f, nullptr),
229  "");
230 }

References impeller::LineTo(), and impeller::PathBuilder::MoveTo().

◆ TEST() [221/360]

impeller::testing::TEST ( PathTest  ,
PolylineGetContourPointBoundsReturnsCorrectRanges   
)

Definition at line 142 of file path_unittests.cc.

142  {
143  Path::Polyline polyline = PathBuilder{}
144  .AddLine({100, 100}, {200, 100})
145  .MoveTo({100, 200})
146  .LineTo({150, 250})
147  .LineTo({200, 200})
148  .Close()
149  .TakePath()
150  .CreatePolyline(1.0f);
151  size_t a1, a2, b1, b2;
152  std::tie(a1, a2) = polyline.GetContourPointBounds(0);
153  std::tie(b1, b2) = polyline.GetContourPointBounds(1);
154  ASSERT_EQ(a1, 0u);
155  ASSERT_EQ(a2, 2u);
156  ASSERT_EQ(b1, 2u);
157  ASSERT_EQ(b2, 6u);
158 }

References impeller::PathBuilder::AddLine(), impeller::Close(), impeller::LineTo(), impeller::MoveTo(), and polyline.

◆ TEST() [222/360]

impeller::testing::TEST ( PathTest  ,
QuadradicPath   
)

Definition at line 312 of file path_unittests.cc.

312  {
313  PathBuilder builder;
314  auto path = builder.QuadraticCurveTo(Point(10, 10), Point(20, 20)).TakePath();
315 
316  QuadraticPathComponent quad;
317  path.GetQuadraticComponentAtIndex(1, quad);
318 
319  EXPECT_EQ(quad.p1, Point(0, 0));
320  EXPECT_EQ(quad.cp, Point(10, 10));
321  EXPECT_EQ(quad.p2, Point(20, 20));
322 }

References impeller::QuadraticPathComponent::cp, impeller::QuadraticPathComponent::p1, impeller::QuadraticPathComponent::p2, impeller::PathBuilder::QuadraticCurveTo(), and impeller::PathBuilder::TakePath().

◆ TEST() [223/360]

impeller::testing::TEST ( PathTest  ,
RepeatCloseDoesNotAddNewLines   
)

Definition at line 457 of file path_unittests.cc.

457  {
458  PathBuilder builder;
459  auto path = builder.LineTo({0, 10})
460  .LineTo({10, 10})
461  .Close() // Returns to (0, 0)
462  .Close() // No Op
463  .Close() // Still No op
464  .TakePath();
465 
466  EXPECT_EQ(path.GetComponentCount(), 5u);
467  EXPECT_EQ(path.GetComponentCount(Path::ComponentType::kLinear), 3u);
468  EXPECT_EQ(path.GetComponentCount(Path::ComponentType::kContour), 2u);
469 }

References impeller::Close(), impeller::Path::kContour, impeller::Path::kLinear, impeller::LineTo(), and impeller::PathBuilder::LineTo().

◆ TEST() [224/360]

impeller::testing::TEST ( PathTest  ,
SimplePath   
)

Definition at line 397 of file path_unittests.cc.

397  {
398  PathBuilder builder;
399 
400  auto path = builder.AddLine({0, 0}, {100, 100})
401  .AddQuadraticCurve({100, 100}, {200, 200}, {300, 300})
402  .AddCubicCurve({300, 300}, {400, 400}, {500, 500}, {600, 600})
403  .TakePath();
404 
405  ASSERT_EQ(path.GetComponentCount(), 6u);
406  ASSERT_EQ(path.GetComponentCount(Path::ComponentType::kLinear), 1u);
407  ASSERT_EQ(path.GetComponentCount(Path::ComponentType::kQuadratic), 1u);
408  ASSERT_EQ(path.GetComponentCount(Path::ComponentType::kCubic), 1u);
409  ASSERT_EQ(path.GetComponentCount(Path::ComponentType::kContour), 3u);
410 
411  path.EnumerateComponents(
412  [](size_t index, const LinearPathComponent& linear) {
413  Point p1(0, 0);
414  Point p2(100, 100);
415  ASSERT_EQ(index, 1u);
416  ASSERT_EQ(linear.p1, p1);
417  ASSERT_EQ(linear.p2, p2);
418  },
419  [](size_t index, const QuadraticPathComponent& quad) {
420  Point p1(100, 100);
421  Point cp(200, 200);
422  Point p2(300, 300);
423  ASSERT_EQ(index, 3u);
424  ASSERT_EQ(quad.p1, p1);
425  ASSERT_EQ(quad.cp, cp);
426  ASSERT_EQ(quad.p2, p2);
427  },
428  [](size_t index, const CubicPathComponent& cubic) {
429  Point p1(300, 300);
430  Point cp1(400, 400);
431  Point cp2(500, 500);
432  Point p2(600, 600);
433  ASSERT_EQ(index, 5u);
434  ASSERT_EQ(cubic.p1, p1);
435  ASSERT_EQ(cubic.cp1, cp1);
436  ASSERT_EQ(cubic.cp2, cp2);
437  ASSERT_EQ(cubic.p2, p2);
438  },
439  [](size_t index, const ContourComponent& contour) {
440  // There is an initial countour added for each curve.
441  if (index == 0u) {
442  Point p1(0, 0);
443  ASSERT_EQ(contour.destination, p1);
444  } else if (index == 2u) {
445  Point p1(100, 100);
446  ASSERT_EQ(contour.destination, p1);
447  } else if (index == 4u) {
448  Point p1(300, 300);
449  ASSERT_EQ(contour.destination, p1);
450  } else {
451  ASSERT_FALSE(true);
452  }
453  ASSERT_FALSE(contour.is_closed);
454  });
455 }

References impeller::PathBuilder::AddLine(), impeller::Path::kContour, impeller::Path::kCubic, impeller::Path::kLinear, impeller::Path::kQuadratic, impeller::LinearPathComponent::p1, and impeller::LinearPathComponent::p2.

◆ TEST() [225/360]

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

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 }

◆ TEST() [227/360]

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 }

◆ TEST() [228/360]

impeller::testing::TEST ( RectTest  ,
ContainsFloatingPoint   
)

Definition at line 1271 of file rect_unittests.cc.

1271  {
1272  auto rect1 =
1273  Rect::MakeXYWH(472.599945f, 440.999969f, 1102.80005f, 654.000061f);
1274  auto rect2 = Rect::MakeXYWH(724.f, 618.f, 600.f, 300.f);
1275  EXPECT_TRUE(rect1.Contains(rect2));
1276 }

References impeller::TRect< Scalar >::MakeXYWH().

◆ TEST() [229/360]

impeller::testing::TEST ( RectTest  ,
EmptyIRectDoesNotIntersect   
)

Definition at line 854 of file rect_unittests.cc.

854  {
855  IRect rect = IRect::MakeLTRB(50, 50, 100, 100);
856 
857  auto test = [&rect](int64_t l, int64_t t, int64_t r, int64_t b,
858  const std::string& label) {
859  EXPECT_FALSE(IRect::MakeLTRB(l, b, r, t).IntersectsWithRect(rect))
860  << label << " with Top/Bottom swapped";
861  EXPECT_FALSE(IRect::MakeLTRB(r, b, l, t).IntersectsWithRect(rect))
862  << label << " with Left/Right swapped";
863  EXPECT_FALSE(IRect::MakeLTRB(r, t, l, b).IntersectsWithRect(rect))
864  << label << " with all sides swapped";
865  };
866 
867  test(20, 20, 30, 30, "Above and Left");
868  test(70, 20, 80, 30, "Above");
869  test(120, 20, 130, 30, "Above and Right");
870  test(120, 70, 130, 80, "Right");
871  test(120, 120, 130, 130, "Below and Right");
872  test(70, 120, 80, 130, "Below");
873  test(20, 120, 30, 130, "Below and Left");
874  test(20, 70, 30, 80, "Left");
875 
876  test(70, 70, 80, 80, "Inside");
877 
878  test(40, 70, 60, 80, "Straddling Left");
879  test(70, 40, 80, 60, "Straddling Top");
880  test(90, 70, 110, 80, "Straddling Right");
881  test(70, 90, 80, 110, "Straddling Bottom");
882 }

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

◆ TEST() [230/360]

impeller::testing::TEST ( RectTest  ,
EmptyRectDoesNotIntersect   
)

Definition at line 824 of file rect_unittests.cc.

824  {
825  Rect rect = Rect::MakeLTRB(50, 50, 100, 100);
826 
827  auto test = [&rect](Scalar l, Scalar t, Scalar r, Scalar b,
828  const std::string& label) {
829  EXPECT_FALSE(Rect::MakeLTRB(l, b, r, t).IntersectsWithRect(rect))
830  << label << " with Top/Bottom swapped";
831  EXPECT_FALSE(Rect::MakeLTRB(r, b, l, t).IntersectsWithRect(rect))
832  << label << " with Left/Right swapped";
833  EXPECT_FALSE(Rect::MakeLTRB(r, t, l, b).IntersectsWithRect(rect))
834  << label << " with all sides swapped";
835  };
836 
837  test(20, 20, 30, 30, "Above and Left");
838  test(70, 20, 80, 30, "Above");
839  test(120, 20, 130, 30, "Above and Right");
840  test(120, 70, 130, 80, "Right");
841  test(120, 120, 130, 130, "Below and Right");
842  test(70, 120, 80, 130, "Below");
843  test(20, 120, 30, 130, "Below and Left");
844  test(20, 70, 30, 80, "Left");
845 
846  test(70, 70, 80, 80, "Inside");
847 
848  test(40, 70, 60, 80, "Straddling Left");
849  test(70, 40, 80, 60, "Straddling Top");
850  test(90, 70, 110, 80, "Straddling Right");
851  test(70, 90, 80, 110, "Straddling Bottom");
852 }

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

◆ TEST() [231/360]

impeller::testing::TEST ( RectTest  ,
GetCenter   
)

Definition at line 1194 of file rect_unittests.cc.

1194  {
1195  EXPECT_EQ(Rect::MakeXYWH(10, 30, 20, 20).GetCenter(), Point(20, 40));
1196  EXPECT_EQ(Rect::MakeXYWH(10, 30, 20, 19).GetCenter(), Point(20, 39.5));
1197  EXPECT_EQ(Rect::MakeMaximum().GetCenter(), Point(0, 0));
1198 
1199  // Note that we expect a Point as the answer from an IRect
1200  EXPECT_EQ(IRect::MakeXYWH(10, 30, 20, 20).GetCenter(), Point(20, 40));
1201  EXPECT_EQ(IRect::MakeXYWH(10, 30, 20, 19).GetCenter(), Point(20, 39.5));
1202  EXPECT_EQ(IRect::MakeMaximum().GetCenter(), Point(0, 0));
1203 }

References impeller::TRect< Scalar >::MakeMaximum(), impeller::TRect< T >::MakeMaximum(), impeller::TRect< T >::MakeXYWH(), and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST() [232/360]

impeller::testing::TEST ( RectTest  ,
IRectArea   
)

Definition at line 980 of file rect_unittests.cc.

980  {
981  EXPECT_EQ(IRect::MakeXYWH(0, 0, 100, 200).Area(), 20000);
982  EXPECT_EQ(IRect::MakeXYWH(10, 20, 100, 200).Area(), 20000);
983  EXPECT_EQ(IRect::MakeXYWH(0, 0, 200, 100).Area(), 20000);
984  EXPECT_EQ(IRect::MakeXYWH(10, 20, 200, 100).Area(), 20000);
985  EXPECT_EQ(IRect::MakeXYWH(0, 0, 100, 100).Area(), 10000);
986  EXPECT_EQ(IRect::MakeXYWH(10, 20, 100, 100).Area(), 10000);
987 }

References impeller::TRect< T >::MakeXYWH().

◆ TEST() [233/360]

impeller::testing::TEST ( RectTest  ,
IRectContainsInclusiveIPoint   
)

Definition at line 2355 of file rect_unittests.cc.

2355  {
2356  auto check_empty_flips = [](const IRect& rect, const IPoint& point,
2357  const std::string& label) {
2358  ASSERT_FALSE(rect.IsEmpty());
2359 
2360  EXPECT_FALSE(flip_lr(rect).ContainsInclusive(point)) << label;
2361  EXPECT_FALSE(flip_tb(rect).ContainsInclusive(point)) << label;
2362  EXPECT_FALSE(flip_lrtb(rect).ContainsInclusive(point)) << label;
2363  };
2364 
2365  auto test_inside = [&check_empty_flips](const IRect& rect,
2366  const IPoint& point) {
2367  ASSERT_FALSE(rect.IsEmpty()) << rect;
2368 
2369  std::stringstream stream;
2370  stream << rect << " contains " << point;
2371  auto label = stream.str();
2372 
2373  EXPECT_TRUE(rect.ContainsInclusive(point)) << label;
2374  check_empty_flips(rect, point, label);
2375  };
2376 
2377  auto test_outside = [&check_empty_flips](const IRect& rect,
2378  const IPoint& point) {
2379  ASSERT_FALSE(rect.IsEmpty()) << rect;
2380 
2381  std::stringstream stream;
2382  stream << rect << " contains " << point;
2383  auto label = stream.str();
2384 
2385  EXPECT_FALSE(rect.ContainsInclusive(point)) << label;
2386  check_empty_flips(rect, point, label);
2387  };
2388 
2389  {
2390  // Origin is inclusive
2391  auto r = IRect::MakeXYWH(100, 100, 100, 100);
2392  auto p = IPoint(100, 100);
2393 
2394  test_inside(r, p);
2395  }
2396  {
2397  // Size is inclusive
2398  auto r = IRect::MakeXYWH(100, 100, 100, 100);
2399  auto p = IPoint(200, 200);
2400 
2401  test_inside(r, p);
2402  }
2403  {
2404  // Size + "epsilon" is exclusive
2405  auto r = IRect::MakeXYWH(100, 100, 100, 100);
2406  auto p = IPoint(201, 201);
2407 
2408  test_outside(r, p);
2409  }
2410  {
2411  auto r = IRect::MakeXYWH(100, 100, 100, 100);
2412  auto p = IPoint(99, 99);
2413 
2414  test_outside(r, p);
2415  }
2416  {
2417  auto r = IRect::MakeXYWH(100, 100, 100, 100);
2418  auto p = IPoint(199, 199);
2419 
2420  test_inside(r, p);
2421  }
2422 
2423  {
2424  auto r = IRect::MakeMaximum();
2425  auto p = IPoint(199, 199);
2426 
2427  test_inside(r, p);
2428  }
2429 }

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

impeller::testing::TEST ( RectTest  ,
IRectContainsIPoint   
)

Definition at line 2193 of file rect_unittests.cc.

2193  {
2194  auto check_empty_flips = [](const IRect& rect, const IPoint& point,
2195  const std::string& label) {
2196  ASSERT_FALSE(rect.IsEmpty());
2197 
2198  EXPECT_FALSE(flip_lr(rect).Contains(point)) << label;
2199  EXPECT_FALSE(flip_tb(rect).Contains(point)) << label;
2200  EXPECT_FALSE(flip_lrtb(rect).Contains(point)) << label;
2201  };
2202 
2203  auto test_inside = [&check_empty_flips](const IRect& rect,
2204  const IPoint& point) {
2205  ASSERT_FALSE(rect.IsEmpty()) << rect;
2206 
2207  std::stringstream stream;
2208  stream << rect << " contains " << point;
2209  auto label = stream.str();
2210 
2211  EXPECT_TRUE(rect.Contains(point)) << label;
2212  check_empty_flips(rect, point, label);
2213  };
2214 
2215  auto test_outside = [&check_empty_flips](const IRect& rect,
2216  const IPoint& point) {
2217  ASSERT_FALSE(rect.IsEmpty()) << rect;
2218 
2219  std::stringstream stream;
2220  stream << rect << " contains " << point;
2221  auto label = stream.str();
2222 
2223  EXPECT_FALSE(rect.Contains(point)) << label;
2224  check_empty_flips(rect, point, label);
2225  };
2226 
2227  {
2228  // Origin is inclusive
2229  auto r = IRect::MakeXYWH(100, 100, 100, 100);
2230  auto p = IPoint(100, 100);
2231 
2232  test_inside(r, p);
2233  }
2234  {
2235  // Size is exclusive
2236  auto r = IRect::MakeXYWH(100, 100, 100, 100);
2237  auto p = IPoint(200, 200);
2238 
2239  test_outside(r, p);
2240  }
2241  {
2242  auto r = IRect::MakeXYWH(100, 100, 100, 100);
2243  auto p = IPoint(99, 99);
2244 
2245  test_outside(r, p);
2246  }
2247  {
2248  auto r = IRect::MakeXYWH(100, 100, 100, 100);
2249  auto p = IPoint(199, 199);
2250 
2251  test_inside(r, p);
2252  }
2253 
2254  {
2255  auto r = IRect::MakeMaximum();
2256  auto p = IPoint(199, 199);
2257 
2258  test_inside(r, p);
2259  }
2260 }

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

impeller::testing::TEST ( RectTest  ,
IRectContainsIRect   
)

Definition at line 2546 of file rect_unittests.cc.

2546  {
2547  auto check_empty_flips = [](const IRect& a, const IRect& b,
2548  const std::string& label) {
2549  ASSERT_FALSE(a.IsEmpty());
2550  // test b rects are allowed to have 0 w/h, but not be backwards
2551  ASSERT_FALSE(b.GetLeft() > b.GetRight() || b.GetTop() > b.GetBottom());
2552 
2553  // unflipped a vs flipped (empty) b yields true
2554  EXPECT_TRUE(a.Contains(flip_lr(b))) << label;
2555  EXPECT_TRUE(a.Contains(flip_tb(b))) << label;
2556  EXPECT_TRUE(a.Contains(flip_lrtb(b))) << label;
2557 
2558  // flipped (empty) a vs unflipped b yields false
2559  EXPECT_FALSE(flip_lr(a).Contains(b)) << label;
2560  EXPECT_FALSE(flip_tb(a).Contains(b)) << label;
2561  EXPECT_FALSE(flip_lrtb(a).Contains(b)) << label;
2562 
2563  // flipped (empty) a vs flipped (empty) b yields empty
2564  EXPECT_FALSE(flip_lr(a).Contains(flip_lr(b))) << label;
2565  EXPECT_FALSE(flip_tb(a).Contains(flip_tb(b))) << label;
2566  EXPECT_FALSE(flip_lrtb(a).Contains(flip_lrtb(b))) << label;
2567  };
2568 
2569  auto test_inside = [&check_empty_flips](const IRect& a, const IRect& b) {
2570  ASSERT_FALSE(a.IsEmpty()) << a;
2571  // test b rects are allowed to have 0 w/h, but not be backwards
2572  ASSERT_FALSE(b.GetLeft() > b.GetRight() || b.GetTop() > b.GetBottom());
2573 
2574  std::stringstream stream;
2575  stream << a << " contains " << b;
2576  auto label = stream.str();
2577 
2578  EXPECT_TRUE(a.Contains(b)) << label;
2579  check_empty_flips(a, b, label);
2580  };
2581 
2582  auto test_not_inside = [&check_empty_flips](const IRect& a, const IRect& b) {
2583  ASSERT_FALSE(a.IsEmpty()) << a;
2584  // If b was empty, it would be contained and should not be tested with
2585  // this function - use |test_inside| instead.
2586  ASSERT_FALSE(b.IsEmpty()) << b;
2587 
2588  std::stringstream stream;
2589  stream << a << " contains " << b;
2590  auto label = stream.str();
2591 
2592  EXPECT_FALSE(a.Contains(b)) << label;
2593  check_empty_flips(a, b, label);
2594  };
2595 
2596  {
2597  auto a = IRect::MakeXYWH(100, 100, 100, 100);
2598 
2599  test_inside(a, a);
2600  }
2601  {
2602  auto a = IRect::MakeXYWH(100, 100, 100, 100);
2603  auto b = IRect::MakeXYWH(0, 0, 0, 0);
2604 
2605  test_inside(a, b);
2606  }
2607  {
2608  auto a = IRect::MakeXYWH(100, 100, 100, 100);
2609  auto b = IRect::MakeXYWH(150, 150, 20, 20);
2610 
2611  test_inside(a, b);
2612  }
2613  {
2614  auto a = IRect::MakeXYWH(100, 100, 100, 100);
2615  auto b = IRect::MakeXYWH(150, 150, 100, 100);
2616 
2617  test_not_inside(a, b);
2618  }
2619  {
2620  auto a = IRect::MakeXYWH(100, 100, 100, 100);
2621  auto b = IRect::MakeXYWH(50, 50, 100, 100);
2622 
2623  test_not_inside(a, b);
2624  }
2625  {
2626  auto a = IRect::MakeXYWH(100, 100, 100, 100);
2627  auto b = IRect::MakeXYWH(0, 0, 300, 300);
2628 
2629  test_not_inside(a, b);
2630  }
2631  {
2632  auto a = IRect::MakeMaximum();
2633  auto b = IRect::MakeXYWH(0, 0, 300, 300);
2634 
2635  test_inside(a, b);
2636  }
2637 }

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

impeller::testing::TEST ( RectTest  ,
IRectCopy   
)

Definition at line 641 of file rect_unittests.cc.

641  {
642  IRect rect = IRect::MakeLTRB(5, 10, 20, 25);
643  IRect copy = rect;
644 
645  EXPECT_EQ(rect, copy);
646  EXPECT_EQ(copy.GetLeft(), 5);
647  EXPECT_EQ(copy.GetTop(), 10);
648  EXPECT_EQ(copy.GetRight(), 20);
649  EXPECT_EQ(copy.GetBottom(), 25);
650  EXPECT_EQ(copy.GetX(), 5);
651  EXPECT_EQ(copy.GetY(), 10);
652  EXPECT_EQ(copy.GetWidth(), 15);
653  EXPECT_EQ(copy.GetHeight(), 15);
654  EXPECT_FALSE(copy.IsEmpty());
655 }

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

impeller::testing::TEST ( RectTest  ,
IRectCutOut   
)

Definition at line 2791 of file rect_unittests.cc.

2791  {
2792  IRect cull_rect = IRect::MakeLTRB(20, 20, 40, 40);
2793 
2794  auto check_empty_flips = [&cull_rect](const IRect& diff_rect,
2795  const std::string& label) {
2796  EXPECT_FALSE(diff_rect.IsEmpty());
2797  EXPECT_FALSE(cull_rect.IsEmpty());
2798 
2799  // unflipped cull_rect vs flipped(empty) diff_rect
2800  // == cull_rect
2801  EXPECT_TRUE(cull_rect.Cutout(flip_lr(diff_rect)).has_value()) << label;
2802  EXPECT_EQ(cull_rect.Cutout(flip_lr(diff_rect)), cull_rect) << label;
2803  EXPECT_TRUE(cull_rect.Cutout(flip_tb(diff_rect)).has_value()) << label;
2804  EXPECT_EQ(cull_rect.Cutout(flip_tb(diff_rect)), cull_rect) << label;
2805  EXPECT_TRUE(cull_rect.Cutout(flip_lrtb(diff_rect)).has_value()) << label;
2806  EXPECT_EQ(cull_rect.Cutout(flip_lrtb(diff_rect)), cull_rect) << label;
2807 
2808  // flipped(empty) cull_rect vs flipped(empty) diff_rect
2809  // == empty
2810  EXPECT_FALSE(flip_lr(cull_rect).Cutout(diff_rect).has_value()) << label;
2811  EXPECT_EQ(flip_lr(cull_rect).CutoutOrEmpty(diff_rect), IRect()) << label;
2812  EXPECT_FALSE(flip_tb(cull_rect).Cutout(diff_rect).has_value()) << label;
2813  EXPECT_EQ(flip_tb(cull_rect).CutoutOrEmpty(diff_rect), IRect()) << label;
2814  EXPECT_FALSE(flip_lrtb(cull_rect).Cutout(diff_rect).has_value()) << label;
2815  EXPECT_EQ(flip_lrtb(cull_rect).CutoutOrEmpty(diff_rect), IRect()) << label;
2816 
2817  // flipped(empty) cull_rect vs unflipped diff_rect
2818  // == empty
2819  EXPECT_FALSE(flip_lr(cull_rect).Cutout(flip_lr(diff_rect)).has_value())
2820  << label;
2821  EXPECT_EQ(flip_lr(cull_rect).CutoutOrEmpty(flip_lr(diff_rect)), IRect())
2822  << label;
2823  EXPECT_FALSE(flip_tb(cull_rect).Cutout(flip_tb(diff_rect)).has_value())
2824  << label;
2825  EXPECT_EQ(flip_tb(cull_rect).CutoutOrEmpty(flip_tb(diff_rect)), IRect())
2826  << label;
2827  EXPECT_FALSE(flip_lrtb(cull_rect).Cutout(flip_lrtb(diff_rect)).has_value())
2828  << label;
2829  EXPECT_EQ(flip_lrtb(cull_rect).CutoutOrEmpty(flip_lrtb(diff_rect)), IRect())
2830  << label;
2831  };
2832 
2833  auto non_reducing = [&cull_rect, &check_empty_flips](
2834  const IRect& diff_rect, const std::string& label) {
2835  EXPECT_EQ(cull_rect.Cutout(diff_rect), cull_rect) << label;
2836  EXPECT_EQ(cull_rect.CutoutOrEmpty(diff_rect), cull_rect) << label;
2837  check_empty_flips(diff_rect, label);
2838  };
2839 
2840  auto reducing = [&cull_rect, &check_empty_flips](const IRect& diff_rect,
2841  const IRect& result_rect,
2842  const std::string& label) {
2843  EXPECT_TRUE(!result_rect.IsEmpty());
2844  EXPECT_EQ(cull_rect.Cutout(diff_rect), result_rect) << label;
2845  EXPECT_EQ(cull_rect.CutoutOrEmpty(diff_rect), result_rect) << label;
2846  check_empty_flips(diff_rect, label);
2847  };
2848 
2849  auto emptying = [&cull_rect, &check_empty_flips](const IRect& diff_rect,
2850  const std::string& label) {
2851  EXPECT_FALSE(cull_rect.Cutout(diff_rect).has_value()) << label;
2852  EXPECT_EQ(cull_rect.CutoutOrEmpty(diff_rect), IRect()) << label;
2853  check_empty_flips(diff_rect, label);
2854  };
2855 
2856  // Skim the corners and edge
2857  non_reducing(IRect::MakeLTRB(10, 10, 20, 20), "outside UL corner");
2858  non_reducing(IRect::MakeLTRB(20, 10, 40, 20), "Above");
2859  non_reducing(IRect::MakeLTRB(40, 10, 50, 20), "outside UR corner");
2860  non_reducing(IRect::MakeLTRB(40, 20, 50, 40), "Right");
2861  non_reducing(IRect::MakeLTRB(40, 40, 50, 50), "outside LR corner");
2862  non_reducing(IRect::MakeLTRB(20, 40, 40, 50), "Below");
2863  non_reducing(IRect::MakeLTRB(10, 40, 20, 50), "outside LR corner");
2864  non_reducing(IRect::MakeLTRB(10, 20, 20, 40), "Left");
2865 
2866  // Overlap corners
2867  non_reducing(IRect::MakeLTRB(15, 15, 25, 25), "covering UL corner");
2868  non_reducing(IRect::MakeLTRB(35, 15, 45, 25), "covering UR corner");
2869  non_reducing(IRect::MakeLTRB(35, 35, 45, 45), "covering LR corner");
2870  non_reducing(IRect::MakeLTRB(15, 35, 25, 45), "covering LL corner");
2871 
2872  // Overlap edges, but not across an entire side
2873  non_reducing(IRect::MakeLTRB(20, 15, 39, 25), "Top edge left-biased");
2874  non_reducing(IRect::MakeLTRB(21, 15, 40, 25), "Top edge, right biased");
2875  non_reducing(IRect::MakeLTRB(35, 20, 45, 39), "Right edge, top-biased");
2876  non_reducing(IRect::MakeLTRB(35, 21, 45, 40), "Right edge, bottom-biased");
2877  non_reducing(IRect::MakeLTRB(20, 35, 39, 45), "Bottom edge, left-biased");
2878  non_reducing(IRect::MakeLTRB(21, 35, 40, 45), "Bottom edge, right-biased");
2879  non_reducing(IRect::MakeLTRB(15, 20, 25, 39), "Left edge, top-biased");
2880  non_reducing(IRect::MakeLTRB(15, 21, 25, 40), "Left edge, bottom-biased");
2881 
2882  // Slice all the way through the middle
2883  non_reducing(IRect::MakeLTRB(25, 15, 35, 45), "Vertical interior slice");
2884  non_reducing(IRect::MakeLTRB(15, 25, 45, 35), "Horizontal interior slice");
2885 
2886  // Slice off each edge
2887  reducing(IRect::MakeLTRB(20, 15, 40, 25), //
2888  IRect::MakeLTRB(20, 25, 40, 40), //
2889  "Slice off top");
2890  reducing(IRect::MakeLTRB(35, 20, 45, 40), //
2891  IRect::MakeLTRB(20, 20, 35, 40), //
2892  "Slice off right");
2893  reducing(IRect::MakeLTRB(20, 35, 40, 45), //
2894  IRect::MakeLTRB(20, 20, 40, 35), //
2895  "Slice off bottom");
2896  reducing(IRect::MakeLTRB(15, 20, 25, 40), //
2897  IRect::MakeLTRB(25, 20, 40, 40), //
2898  "Slice off left");
2899 
2900  // cull rect contains diff rect
2901  non_reducing(IRect::MakeLTRB(21, 21, 39, 39), "Contained, non-covering");
2902 
2903  // cull rect equals diff rect
2904  emptying(cull_rect, "Perfectly covering");
2905 
2906  // diff rect contains cull rect
2907  emptying(IRect::MakeLTRB(15, 15, 45, 45), "Smothering");
2908 }

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

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

impeller::testing::TEST ( RectTest  ,
IRectDoesNotIntersectEmpty   
)

Definition at line 794 of file rect_unittests.cc.

794  {
795  IRect rect = IRect::MakeLTRB(50, 50, 100, 100);
796 
797  auto test = [&rect](int64_t l, int64_t t, int64_t r, int64_t b,
798  const std::string& label) {
799  EXPECT_FALSE(rect.IntersectsWithRect(IRect::MakeLTRB(l, b, r, t)))
800  << label << " with Top/Bottom swapped";
801  EXPECT_FALSE(rect.IntersectsWithRect(IRect::MakeLTRB(r, b, l, t)))
802  << label << " with Left/Right swapped";
803  EXPECT_FALSE(rect.IntersectsWithRect(IRect::MakeLTRB(r, t, l, b)))
804  << label << " with all sides swapped";
805  };
806 
807  test(20, 20, 30, 30, "Above and Left");
808  test(70, 20, 80, 30, "Above");
809  test(120, 20, 130, 30, "Above and Right");
810  test(120, 70, 130, 80, "Right");
811  test(120, 120, 130, 130, "Below and Right");
812  test(70, 120, 80, 130, "Below");
813  test(20, 120, 30, 130, "Below and Left");
814  test(20, 70, 30, 80, "Left");
815 
816  test(70, 70, 80, 80, "Inside");
817 
818  test(40, 70, 60, 80, "Straddling Left");
819  test(70, 40, 80, 60, "Straddling Top");
820  test(90, 70, 110, 80, "Straddling Right");
821  test(70, 90, 80, 110, "Straddling Bottom");
822 }

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

◆ TEST() [240/360]

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

impeller::testing::TEST ( RectTest  ,
IRectExpand   
)

Definition at line 1238 of file rect_unittests.cc.

1238  {
1239  auto rect = IRect::MakeLTRB(100, 100, 200, 200);
1240 
1241  // Expand(T amount)
1242  EXPECT_EQ(rect.Expand(10), IRect::MakeLTRB(90, 90, 210, 210));
1243  EXPECT_EQ(rect.Expand(-10), IRect::MakeLTRB(110, 110, 190, 190));
1244 
1245  // Expand(amount, amount)
1246  EXPECT_EQ(rect.Expand(10, 10), IRect::MakeLTRB(90, 90, 210, 210));
1247  EXPECT_EQ(rect.Expand(10, -10), IRect::MakeLTRB(90, 110, 210, 190));
1248  EXPECT_EQ(rect.Expand(-10, 10), IRect::MakeLTRB(110, 90, 190, 210));
1249  EXPECT_EQ(rect.Expand(-10, -10), IRect::MakeLTRB(110, 110, 190, 190));
1250 
1251  // Expand(amount, amount, amount, amount)
1252  EXPECT_EQ(rect.Expand(10, 20, 30, 40), IRect::MakeLTRB(90, 80, 230, 240));
1253  EXPECT_EQ(rect.Expand(-10, 20, 30, 40), IRect::MakeLTRB(110, 80, 230, 240));
1254  EXPECT_EQ(rect.Expand(10, -20, 30, 40), IRect::MakeLTRB(90, 120, 230, 240));
1255  EXPECT_EQ(rect.Expand(10, 20, -30, 40), IRect::MakeLTRB(90, 80, 170, 240));
1256  EXPECT_EQ(rect.Expand(10, 20, 30, -40), IRect::MakeLTRB(90, 80, 230, 160));
1257 
1258  // Expand(IPoint amount)
1259  EXPECT_EQ(rect.Expand(IPoint{10, 10}), IRect::MakeLTRB(90, 90, 210, 210));
1260  EXPECT_EQ(rect.Expand(IPoint{10, -10}), IRect::MakeLTRB(90, 110, 210, 190));
1261  EXPECT_EQ(rect.Expand(IPoint{-10, 10}), IRect::MakeLTRB(110, 90, 190, 210));
1262  EXPECT_EQ(rect.Expand(IPoint{-10, -10}), IRect::MakeLTRB(110, 110, 190, 190));
1263 
1264  // Expand(ISize amount)
1265  EXPECT_EQ(rect.Expand(ISize{10, 10}), IRect::MakeLTRB(90, 90, 210, 210));
1266  EXPECT_EQ(rect.Expand(ISize{10, -10}), IRect::MakeLTRB(90, 110, 210, 190));
1267  EXPECT_EQ(rect.Expand(ISize{-10, 10}), IRect::MakeLTRB(110, 90, 190, 210));
1268  EXPECT_EQ(rect.Expand(ISize{-10, -10}), IRect::MakeLTRB(110, 110, 190, 190));
1269 }

References impeller::TRect< T >::MakeLTRB().

◆ TEST() [242/360]

impeller::testing::TEST ( RectTest  ,
IRectFromIRect   
)

Definition at line 616 of file rect_unittests.cc.

616  {
617  EXPECT_EQ(IRect(IRect::MakeXYWH(2, 3, 7, 15)), //
618  IRect::MakeXYWH(2, 3, 7, 15));
619  EXPECT_EQ(IRect(IRect::MakeLTRB(2, 3, 7, 15)), //
620  IRect::MakeLTRB(2, 3, 7, 15));
621 }

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

◆ TEST() [243/360]

impeller::testing::TEST ( RectTest  ,
IRectGetNormalizingTransform   
)

Definition at line 1077 of file rect_unittests.cc.

1077  {
1078  {
1079  // Checks for expected matrix values
1080 
1081  auto r = IRect::MakeXYWH(100, 200, 200, 400);
1082 
1083  EXPECT_EQ(r.GetNormalizingTransform(),
1084  Matrix::MakeScale({0.005, 0.0025, 1.0}) *
1085  Matrix::MakeTranslation({-100, -200}));
1086  }
1087 
1088  {
1089  // Checks for expected transform of points relative to the rect
1090 
1091  auto r = IRect::MakeLTRB(300, 500, 400, 700);
1092  auto m = r.GetNormalizingTransform();
1093 
1094  // The 4 corners of the rect => (0, 0) to (1, 1)
1095  EXPECT_EQ(m * Point(300, 500), Point(0, 0));
1096  EXPECT_EQ(m * Point(400, 500), Point(1, 0));
1097  EXPECT_EQ(m * Point(400, 700), Point(1, 1));
1098  EXPECT_EQ(m * Point(300, 700), Point(0, 1));
1099 
1100  // The center => (0.5, 0.5)
1101  EXPECT_EQ(m * Point(350, 600), Point(0.5, 0.5));
1102 
1103  // Outside the 4 corners => (-1, -1) to (2, 2)
1104  EXPECT_EQ(m * Point(200, 300), Point(-1, -1));
1105  EXPECT_EQ(m * Point(500, 300), Point(2, -1));
1106  EXPECT_EQ(m * Point(500, 900), Point(2, 2));
1107  EXPECT_EQ(m * Point(200, 900), Point(-1, 2));
1108  }
1109 
1110  {
1111  // Checks for behavior with empty rects
1112 
1113  auto zero = Matrix::MakeScale({0.0, 0.0, 1.0});
1114 
1115  // Empty for width and/or height == 0
1116  EXPECT_EQ(IRect::MakeXYWH(10, 10, 0, 10).GetNormalizingTransform(), zero);
1117  EXPECT_EQ(IRect::MakeXYWH(10, 10, 10, 0).GetNormalizingTransform(), zero);
1118  EXPECT_EQ(IRect::MakeXYWH(10, 10, 0, 0).GetNormalizingTransform(), zero);
1119 
1120  // Empty for width and/or height < 0
1121  EXPECT_EQ(IRect::MakeXYWH(10, 10, -1, 10).GetNormalizingTransform(), zero);
1122  EXPECT_EQ(IRect::MakeXYWH(10, 10, 10, -1).GetNormalizingTransform(), zero);
1123  EXPECT_EQ(IRect::MakeXYWH(10, 10, -1, -1).GetNormalizingTransform(), zero);
1124  }
1125 }

References impeller::TRect< T >::MakeLTRB(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeTranslation(), and impeller::TRect< T >::MakeXYWH().

◆ TEST() [244/360]

impeller::testing::TEST ( RectTest  ,
IRectIntersection   
)

Definition at line 1751 of file rect_unittests.cc.

1751  {
1752  auto check_empty_flips = [](const IRect& a, const IRect& b,
1753  const std::string& label) {
1754  ASSERT_FALSE(a.IsEmpty());
1755  // b is allowed to be empty
1756 
1757  // unflipped a vs flipped (empty) b yields a
1758  EXPECT_FALSE(a.Intersection(flip_lr(b)).has_value()) << label;
1759  EXPECT_FALSE(a.Intersection(flip_tb(b)).has_value()) << label;
1760  EXPECT_FALSE(a.Intersection(flip_lrtb(b)).has_value()) << label;
1761 
1762  // flipped (empty) a vs unflipped b yields b
1763  EXPECT_FALSE(flip_lr(a).Intersection(b).has_value()) << label;
1764  EXPECT_FALSE(flip_tb(a).Intersection(b).has_value()) << label;
1765  EXPECT_FALSE(flip_lrtb(a).Intersection(b).has_value()) << label;
1766 
1767  // flipped (empty) a vs flipped (empty) b yields empty
1768  EXPECT_FALSE(flip_lr(a).Intersection(flip_lr(b)).has_value()) << label;
1769  EXPECT_FALSE(flip_tb(a).Intersection(flip_tb(b)).has_value()) << label;
1770  EXPECT_FALSE(flip_lrtb(a).Intersection(flip_lrtb(b)).has_value()) << label;
1771  };
1772 
1773  auto test_non_empty = [&check_empty_flips](const IRect& a, const IRect& b,
1774  const IRect& result) {
1775  ASSERT_FALSE(a.IsEmpty()) << a;
1776  // b is allowed to be empty
1777 
1778  std::stringstream stream;
1779  stream << a << " union " << b;
1780  auto label = stream.str();
1781 
1782  EXPECT_TRUE(a.Intersection(b).has_value()) << label;
1783  EXPECT_TRUE(b.Intersection(a).has_value()) << label;
1784  EXPECT_EQ(a.Intersection(b), result) << label;
1785  EXPECT_EQ(b.Intersection(a), result) << label;
1786  check_empty_flips(a, b, label);
1787  };
1788 
1789  auto test_empty = [&check_empty_flips](const IRect& a, const IRect& b) {
1790  ASSERT_FALSE(a.IsEmpty()) << a;
1791  // b is allowed to be empty
1792 
1793  std::stringstream stream;
1794  stream << a << " union " << b;
1795  auto label = stream.str();
1796 
1797  EXPECT_FALSE(a.Intersection(b).has_value()) << label;
1798  EXPECT_FALSE(b.Intersection(a).has_value()) << label;
1799  check_empty_flips(a, b, label);
1800  };
1801 
1802  {
1803  auto a = IRect::MakeXYWH(100, 100, 100, 100);
1804  auto b = IRect::MakeXYWH(0, 0, 0, 0);
1805 
1806  test_empty(a, b);
1807  }
1808 
1809  {
1810  auto a = IRect::MakeXYWH(100, 100, 100, 100);
1811  auto b = IRect::MakeXYWH(10, 10, 0, 0);
1812 
1813  test_empty(a, b);
1814  }
1815 
1816  {
1817  auto a = IRect::MakeXYWH(0, 0, 100, 100);
1818  auto b = IRect::MakeXYWH(10, 10, 100, 100);
1819  auto expected = IRect::MakeXYWH(10, 10, 90, 90);
1820 
1821  test_non_empty(a, b, expected);
1822  }
1823 
1824  {
1825  auto a = IRect::MakeXYWH(0, 0, 100, 100);
1826  auto b = IRect::MakeXYWH(100, 100, 100, 100);
1827 
1828  test_empty(a, b);
1829  }
1830 
1831  {
1832  auto a = IRect::MakeMaximum();
1833  auto b = IRect::MakeXYWH(10, 10, 300, 300);
1834 
1835  test_non_empty(a, b, b);
1836  }
1837 
1838  {
1839  auto a = IRect::MakeMaximum();
1840  auto b = IRect::MakeMaximum();
1841 
1842  test_non_empty(a, b, IRect::MakeMaximum());
1843  }
1844 }

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

impeller::testing::TEST ( RectTest  ,
IRectIntersectsWithRect   
)

Definition at line 2016 of file rect_unittests.cc.

2016  {
2017  auto check_empty_flips = [](const IRect& a, const IRect& b,
2018  const std::string& label) {
2019  ASSERT_FALSE(a.IsEmpty());
2020  // b is allowed to be empty
2021 
2022  // unflipped a vs flipped (empty) b yields a
2023  EXPECT_FALSE(a.IntersectsWithRect(flip_lr(b))) << label;
2024  EXPECT_FALSE(a.IntersectsWithRect(flip_tb(b))) << label;
2025  EXPECT_FALSE(a.IntersectsWithRect(flip_lrtb(b))) << label;
2026 
2027  // flipped (empty) a vs unflipped b yields b
2028  EXPECT_FALSE(flip_lr(a).IntersectsWithRect(b)) << label;
2029  EXPECT_FALSE(flip_tb(a).IntersectsWithRect(b)) << label;
2030  EXPECT_FALSE(flip_lrtb(a).IntersectsWithRect(b)) << label;
2031 
2032  // flipped (empty) a vs flipped (empty) b yields empty
2033  EXPECT_FALSE(flip_lr(a).IntersectsWithRect(flip_lr(b))) << label;
2034  EXPECT_FALSE(flip_tb(a).IntersectsWithRect(flip_tb(b))) << label;
2035  EXPECT_FALSE(flip_lrtb(a).IntersectsWithRect(flip_lrtb(b))) << label;
2036  };
2037 
2038  auto test_non_empty = [&check_empty_flips](const IRect& a, const IRect& b) {
2039  ASSERT_FALSE(a.IsEmpty()) << a;
2040  // b is allowed to be empty
2041 
2042  std::stringstream stream;
2043  stream << a << " union " << b;
2044  auto label = stream.str();
2045 
2046  EXPECT_TRUE(a.IntersectsWithRect(b)) << label;
2047  EXPECT_TRUE(b.IntersectsWithRect(a)) << label;
2048  check_empty_flips(a, b, label);
2049  };
2050 
2051  auto test_empty = [&check_empty_flips](const IRect& a, const IRect& b) {
2052  ASSERT_FALSE(a.IsEmpty()) << a;
2053  // b is allowed to be empty
2054 
2055  std::stringstream stream;
2056  stream << a << " union " << b;
2057  auto label = stream.str();
2058 
2059  EXPECT_FALSE(a.IntersectsWithRect(b)) << label;
2060  EXPECT_FALSE(b.IntersectsWithRect(a)) << label;
2061  check_empty_flips(a, b, label);
2062  };
2063 
2064  {
2065  auto a = IRect::MakeXYWH(100, 100, 100, 100);
2066  auto b = IRect::MakeXYWH(0, 0, 0, 0);
2067 
2068  test_empty(a, b);
2069  }
2070 
2071  {
2072  auto a = IRect::MakeXYWH(100, 100, 100, 100);
2073  auto b = IRect::MakeXYWH(10, 10, 0, 0);
2074 
2075  test_empty(a, b);
2076  }
2077 
2078  {
2079  auto a = IRect::MakeXYWH(0, 0, 100, 100);
2080  auto b = IRect::MakeXYWH(10, 10, 100, 100);
2081 
2082  test_non_empty(a, b);
2083  }
2084 
2085  {
2086  auto a = IRect::MakeXYWH(0, 0, 100, 100);
2087  auto b = IRect::MakeXYWH(100, 100, 100, 100);
2088 
2089  test_empty(a, b);
2090  }
2091 
2092  {
2093  auto a = IRect::MakeMaximum();
2094  auto b = IRect::MakeXYWH(10, 10, 100, 100);
2095 
2096  test_non_empty(a, b);
2097  }
2098 
2099  {
2100  auto a = IRect::MakeMaximum();
2101  auto b = IRect::MakeMaximum();
2102 
2103  test_non_empty(a, b);
2104  }
2105 }

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

impeller::testing::TEST ( RectTest  ,
IRectMakeMaximum   
)

Definition at line 593 of file rect_unittests.cc.

593  {
594  IRect rect = IRect::MakeMaximum();
595  auto min = std::numeric_limits<int64_t>::min();
596  auto max = std::numeric_limits<int64_t>::max();
597 
598  EXPECT_EQ(rect.GetLeft(), min);
599  EXPECT_EQ(rect.GetTop(), min);
600  EXPECT_EQ(rect.GetRight(), max);
601  EXPECT_EQ(rect.GetBottom(), max);
602  EXPECT_EQ(rect.GetX(), min);
603  EXPECT_EQ(rect.GetY(), min);
604  EXPECT_EQ(rect.GetWidth(), max);
605  EXPECT_EQ(rect.GetHeight(), max);
606  EXPECT_FALSE(rect.IsEmpty());
607 }

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

impeller::testing::TEST ( RectTest  ,
IRectOriginSizeXYWHGetters   
)

Definition at line 683 of file rect_unittests.cc.

683  {
684  {
685  IRect r = IRect::MakeOriginSize({10, 20}, {50, 40});
686  EXPECT_EQ(r.GetOrigin(), IPoint(10, 20));
687  EXPECT_EQ(r.GetSize(), ISize(50, 40));
688  EXPECT_EQ(r.GetX(), 10);
689  EXPECT_EQ(r.GetY(), 20);
690  EXPECT_EQ(r.GetWidth(), 50);
691  EXPECT_EQ(r.GetHeight(), 40);
692  auto expected_array = std::array<int64_t, 4>{10, 20, 50, 40};
693  EXPECT_EQ(r.GetXYWH(), expected_array);
694  }
695 
696  {
697  IRect r = IRect::MakeLTRB(10, 20, 50, 40);
698  EXPECT_EQ(r.GetOrigin(), IPoint(10, 20));
699  EXPECT_EQ(r.GetSize(), ISize(40, 20));
700  EXPECT_EQ(r.GetX(), 10);
701  EXPECT_EQ(r.GetY(), 20);
702  EXPECT_EQ(r.GetWidth(), 40);
703  EXPECT_EQ(r.GetHeight(), 20);
704  auto expected_array = std::array<int64_t, 4>{10, 20, 40, 20};
705  EXPECT_EQ(r.GetXYWH(), expected_array);
706  }
707 }

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

impeller::testing::TEST ( RectTest  ,
IRectOverflowLTRB   
)

Definition at line 478 of file rect_unittests.cc.

478  {
479  auto min = std::numeric_limits<int64_t>::min();
480  auto max = std::numeric_limits<int64_t>::max();
481 
482  // 4 cases
483  // negative l, r near max takes width past max
484  // positive l, r near min takes width below min
485  // negative t, b near max takes width past max
486  // positive t, b near min takes width below min
487 
488  {
489  IRect rect = IRect::MakeLTRB(-10, 10, max - 5, 26);
490 
491  EXPECT_EQ(rect.GetLeft(), -10);
492  EXPECT_EQ(rect.GetTop(), 10);
493  EXPECT_EQ(rect.GetRight(), max - 5);
494  EXPECT_EQ(rect.GetBottom(), 26);
495  EXPECT_EQ(rect.GetX(), -10);
496  EXPECT_EQ(rect.GetY(), 10);
497  EXPECT_EQ(rect.GetWidth(), max);
498  EXPECT_EQ(rect.GetHeight(), 16);
499  EXPECT_FALSE(rect.IsEmpty());
500  }
501 
502  {
503  IRect rect = IRect::MakeLTRB(10, 10, min + 5, 26);
504 
505  EXPECT_EQ(rect.GetLeft(), 10);
506  EXPECT_EQ(rect.GetTop(), 10);
507  EXPECT_EQ(rect.GetRight(), min + 5);
508  EXPECT_EQ(rect.GetBottom(), 26);
509  EXPECT_EQ(rect.GetX(), 10);
510  EXPECT_EQ(rect.GetY(), 10);
511  EXPECT_EQ(rect.GetWidth(), min);
512  EXPECT_EQ(rect.GetHeight(), 16);
513  EXPECT_TRUE(rect.IsEmpty());
514  }
515 
516  {
517  IRect rect = IRect::MakeLTRB(5, -10, 15, max - 5);
518 
519  EXPECT_EQ(rect.GetLeft(), 5);
520  EXPECT_EQ(rect.GetTop(), -10);
521  EXPECT_EQ(rect.GetRight(), 15);
522  EXPECT_EQ(rect.GetBottom(), max - 5);
523  EXPECT_EQ(rect.GetX(), 5);
524  EXPECT_EQ(rect.GetY(), -10);
525  EXPECT_EQ(rect.GetWidth(), 10);
526  EXPECT_EQ(rect.GetHeight(), max);
527  EXPECT_FALSE(rect.IsEmpty());
528  }
529 
530  {
531  IRect rect = IRect::MakeLTRB(5, 10, 15, min + 5);
532 
533  EXPECT_EQ(rect.GetLeft(), 5);
534  EXPECT_EQ(rect.GetTop(), 10);
535  EXPECT_EQ(rect.GetRight(), 15);
536  EXPECT_EQ(rect.GetBottom(), min + 5);
537  EXPECT_EQ(rect.GetX(), 5);
538  EXPECT_EQ(rect.GetY(), 10);
539  EXPECT_EQ(rect.GetWidth(), 10);
540  EXPECT_EQ(rect.GetHeight(), min);
541  EXPECT_TRUE(rect.IsEmpty());
542  }
543 }

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

impeller::testing::TEST ( RectTest  ,
IRectOverflowXYWH   
)

Definition at line 272 of file rect_unittests.cc.

272  {
273  auto min = std::numeric_limits<int64_t>::min();
274  auto max = std::numeric_limits<int64_t>::max();
275 
276  // 4 cases
277  // x near max, positive w takes it past max
278  // x near min, negative w takes it below min
279  // y near max, positive h takes it past max
280  // y near min, negative h takes it below min
281 
282  {
283  IRect rect = IRect::MakeXYWH(max - 5, 10, 10, 16);
284 
285  EXPECT_EQ(rect.GetLeft(), max - 5);
286  EXPECT_EQ(rect.GetTop(), 10);
287  EXPECT_EQ(rect.GetRight(), max);
288  EXPECT_EQ(rect.GetBottom(), 26);
289  EXPECT_EQ(rect.GetX(), max - 5);
290  EXPECT_EQ(rect.GetY(), 10);
291  EXPECT_EQ(rect.GetWidth(), 5);
292  EXPECT_EQ(rect.GetHeight(), 16);
293  EXPECT_FALSE(rect.IsEmpty());
294  }
295 
296  {
297  IRect rect = IRect::MakeXYWH(min + 5, 10, -10, 16);
298 
299  EXPECT_EQ(rect.GetLeft(), min + 5);
300  EXPECT_EQ(rect.GetTop(), 10);
301  EXPECT_EQ(rect.GetRight(), min);
302  EXPECT_EQ(rect.GetBottom(), 26);
303  EXPECT_EQ(rect.GetX(), min + 5);
304  EXPECT_EQ(rect.GetY(), 10);
305  EXPECT_EQ(rect.GetWidth(), -5);
306  EXPECT_EQ(rect.GetHeight(), 16);
307  EXPECT_TRUE(rect.IsEmpty());
308  }
309 
310  {
311  IRect rect = IRect::MakeXYWH(5, max - 10, 10, 16);
312 
313  EXPECT_EQ(rect.GetLeft(), 5);
314  EXPECT_EQ(rect.GetTop(), max - 10);
315  EXPECT_EQ(rect.GetRight(), 15);
316  EXPECT_EQ(rect.GetBottom(), max);
317  EXPECT_EQ(rect.GetX(), 5);
318  EXPECT_EQ(rect.GetY(), max - 10);
319  EXPECT_EQ(rect.GetWidth(), 10);
320  EXPECT_EQ(rect.GetHeight(), 10);
321  EXPECT_FALSE(rect.IsEmpty());
322  }
323 
324  {
325  IRect rect = IRect::MakeXYWH(5, min + 10, 10, -16);
326 
327  EXPECT_EQ(rect.GetLeft(), 5);
328  EXPECT_EQ(rect.GetTop(), min + 10);
329  EXPECT_EQ(rect.GetRight(), 15);
330  EXPECT_EQ(rect.GetBottom(), min);
331  EXPECT_EQ(rect.GetX(), 5);
332  EXPECT_EQ(rect.GetY(), min + 10);
333  EXPECT_EQ(rect.GetWidth(), 10);
334  EXPECT_EQ(rect.GetHeight(), -10);
335  EXPECT_TRUE(rect.IsEmpty());
336  }
337 }

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

impeller::testing::TEST ( RectTest  ,
IRectRound   
)

Definition at line 3049 of file rect_unittests.cc.

3049  {
3050  {
3051  auto r = Rect::MakeLTRB(-100, -200, 300, 400);
3052  auto ir = IRect::MakeLTRB(-100, -200, 300, 400);
3053  EXPECT_EQ(IRect::Round(r), ir);
3054  }
3055  {
3056  auto r = Rect::MakeLTRB(-100.4, -200.4, 300.4, 400.4);
3057  auto ir = IRect::MakeLTRB(-100, -200, 300, 400);
3058  EXPECT_EQ(IRect::Round(r), ir);
3059  }
3060  {
3061  auto r = Rect::MakeLTRB(-100.5, -200.5, 300.5, 400.5);
3062  auto ir = IRect::MakeLTRB(-101, -201, 301, 401);
3063  EXPECT_EQ(IRect::Round(r), ir);
3064  }
3065 }

References impeller::TRect< Scalar >::MakeLTRB(), impeller::TRect< T >::MakeLTRB(), and impeller::TRect< T >::Round().

◆ TEST() [251/360]

impeller::testing::TEST ( RectTest  ,
IRectRoundOut   
)

Definition at line 3021 of file rect_unittests.cc.

3021  {
3022  {
3023  auto r = Rect::MakeLTRB(-100, -200, 300, 400);
3024  auto ir = IRect::MakeLTRB(-100, -200, 300, 400);
3025  EXPECT_EQ(IRect::RoundOut(r), ir);
3026  }
3027  {
3028  auto r = Rect::MakeLTRB(-100.1, -200.1, 300.1, 400.1);
3029  auto ir = IRect::MakeLTRB(-101, -201, 301, 401);
3030  EXPECT_EQ(IRect::RoundOut(r), ir);
3031  }
3032 }

References impeller::TRect< Scalar >::MakeLTRB(), impeller::TRect< T >::MakeLTRB(), and impeller::TRect< T >::RoundOut().

◆ TEST() [252/360]

impeller::testing::TEST ( RectTest  ,
IRectScale   
)

Definition at line 929 of file rect_unittests.cc.

929  {
930  auto test1 = [](IRect rect, int64_t scale) {
931  IRect expected = IRect::MakeXYWH(rect.GetX() * scale, //
932  rect.GetY() * scale, //
933  rect.GetWidth() * scale, //
934  rect.GetHeight() * scale);
935 
936  EXPECT_EQ(rect.Scale(scale), expected) //
937  << rect << " * " << scale;
938  EXPECT_EQ(rect.Scale(scale, scale), expected) //
939  << rect << " * " << scale;
940  EXPECT_EQ(rect.Scale(IPoint(scale, scale)), expected) //
941  << rect << " * " << scale;
942  EXPECT_EQ(rect.Scale(ISize(scale, scale)), expected) //
943  << rect << " * " << scale;
944  };
945 
946  auto test2 = [&test1](IRect rect, int64_t scale_x, int64_t scale_y) {
947  IRect expected = IRect::MakeXYWH(rect.GetX() * scale_x, //
948  rect.GetY() * scale_y, //
949  rect.GetWidth() * scale_x, //
950  rect.GetHeight() * scale_y);
951 
952  EXPECT_EQ(rect.Scale(scale_x, scale_y), expected) //
953  << rect << " * " << scale_x << ", " << scale_y;
954  EXPECT_EQ(rect.Scale(IPoint(scale_x, scale_y)), expected) //
955  << rect << " * " << scale_x << ", " << scale_y;
956  EXPECT_EQ(rect.Scale(ISize(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(IRect::MakeLTRB(10, 15, 100, 150), 2, 3);
964  test2(IRect::MakeLTRB(10, 15, 100, 150), 3, 2);
965  test2(IRect::MakeLTRB(10, 15, -100, 150), 2, 3);
966  test2(IRect::MakeLTRB(10, 15, 100, -150), 2, 3);
967  test2(IRect::MakeLTRB(10, 15, 100, 150), -2, 3);
968  test2(IRect::MakeLTRB(10, 15, 100, 150), 2, -3);
969 }

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(), impeller::TRect< T >::Scale(), and scale.

◆ TEST() [253/360]

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

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

impeller::testing::TEST ( RectTest  ,
IRectUnion   
)

Definition at line 1456 of file rect_unittests.cc.

1456  {
1457  auto check_empty_flips = [](const IRect& a, const IRect& b,
1458  const std::string& label) {
1459  ASSERT_FALSE(a.IsEmpty());
1460  // b is allowed to be empty
1461 
1462  // unflipped a vs flipped (empty) b yields a
1463  EXPECT_EQ(a.Union(flip_lr(b)), a) << label;
1464  EXPECT_EQ(a.Union(flip_tb(b)), a) << label;
1465  EXPECT_EQ(a.Union(flip_lrtb(b)), a) << label;
1466 
1467  // flipped (empty) a vs unflipped b yields b
1468  EXPECT_EQ(flip_lr(a).Union(b), b) << label;
1469  EXPECT_EQ(flip_tb(a).Union(b), b) << label;
1470  EXPECT_EQ(flip_lrtb(a).Union(b), b) << label;
1471 
1472  // flipped (empty) a vs flipped (empty) b yields empty
1473  EXPECT_TRUE(flip_lr(a).Union(flip_lr(b)).IsEmpty()) << label;
1474  EXPECT_TRUE(flip_tb(a).Union(flip_tb(b)).IsEmpty()) << label;
1475  EXPECT_TRUE(flip_lrtb(a).Union(flip_lrtb(b)).IsEmpty()) << label;
1476  };
1477 
1478  auto test = [&check_empty_flips](const IRect& a, const IRect& b,
1479  const IRect& result) {
1480  ASSERT_FALSE(a.IsEmpty()) << a;
1481  // b is allowed to be empty
1482 
1483  std::stringstream stream;
1484  stream << a << " union " << b;
1485  auto label = stream.str();
1486 
1487  EXPECT_EQ(a.Union(b), result) << label;
1488  EXPECT_EQ(b.Union(a), result) << label;
1489  check_empty_flips(a, b, label);
1490  };
1491 
1492  {
1493  auto a = IRect::MakeXYWH(100, 100, 100, 100);
1494  auto b = IRect::MakeXYWH(0, 0, 0, 0);
1495  auto expected = IRect::MakeXYWH(100, 100, 100, 100);
1496  test(a, b, expected);
1497  }
1498 
1499  {
1500  auto a = IRect::MakeXYWH(100, 100, 100, 100);
1501  auto b = IRect::MakeXYWH(0, 0, 1, 1);
1502  auto expected = IRect::MakeXYWH(0, 0, 200, 200);
1503  test(a, b, expected);
1504  }
1505 
1506  {
1507  auto a = IRect::MakeXYWH(100, 100, 100, 100);
1508  auto b = IRect::MakeXYWH(10, 10, 1, 1);
1509  auto expected = IRect::MakeXYWH(10, 10, 190, 190);
1510  test(a, b, expected);
1511  }
1512 
1513  {
1514  auto a = IRect::MakeXYWH(0, 0, 100, 100);
1515  auto b = IRect::MakeXYWH(10, 10, 100, 100);
1516  auto expected = IRect::MakeXYWH(0, 0, 110, 110);
1517  test(a, b, expected);
1518  }
1519 
1520  {
1521  auto a = IRect::MakeXYWH(0, 0, 100, 100);
1522  auto b = IRect::MakeXYWH(100, 100, 100, 100);
1523  auto expected = IRect::MakeXYWH(0, 0, 200, 200);
1524  test(a, b, expected);
1525  }
1526 }

References impeller::saturated::b, flip_lr(), flip_lrtb(), flip_tb(), impeller::TRect< T >::IsEmpty(), impeller::TRect< T >::MakeXYWH(), and impeller::TRect< T >::Union().

◆ TEST() [256/360]

impeller::testing::TEST ( RectTest  ,
IRectXYWHIsEmpty   
)

Definition at line 1151 of file rect_unittests.cc.

1151  {
1152  // Non-empty
1153  EXPECT_FALSE(IRect::MakeXYWH(1, 2, 10, 7).IsEmpty());
1154 
1155  // Empty both width and height both 0 or negative, in all combinations
1156  EXPECT_TRUE(IRect::MakeXYWH(1, 2, 0, 0).IsEmpty());
1157  EXPECT_TRUE(IRect::MakeXYWH(1, 2, -1, -1).IsEmpty());
1158  EXPECT_TRUE(IRect::MakeXYWH(1, 2, -1, 0).IsEmpty());
1159  EXPECT_TRUE(IRect::MakeXYWH(1, 2, 0, -1).IsEmpty());
1160 
1161  // Empty for 0 or negative width or height (but not both at the same time)
1162  EXPECT_TRUE(IRect::MakeXYWH(1, 2, 10, 0).IsEmpty());
1163  EXPECT_TRUE(IRect::MakeXYWH(1, 2, 10, -1).IsEmpty());
1164  EXPECT_TRUE(IRect::MakeXYWH(1, 2, 0, 7).IsEmpty());
1165  EXPECT_TRUE(IRect::MakeXYWH(1, 2, -1, 7).IsEmpty());
1166 }

References impeller::TRect< T >::MakeXYWH().

◆ TEST() [257/360]

impeller::testing::TEST ( RectTest  ,
IsSquare   
)

Definition at line 1182 of file rect_unittests.cc.

1182  {
1183  EXPECT_TRUE(Rect::MakeXYWH(10, 30, 20, 20).IsSquare());
1184  EXPECT_FALSE(Rect::MakeXYWH(10, 30, 20, 19).IsSquare());
1185  EXPECT_FALSE(Rect::MakeXYWH(10, 30, 19, 20).IsSquare());
1186  EXPECT_TRUE(Rect::MakeMaximum().IsSquare());
1187 
1188  EXPECT_TRUE(IRect::MakeXYWH(10, 30, 20, 20).IsSquare());
1189  EXPECT_FALSE(IRect::MakeXYWH(10, 30, 20, 19).IsSquare());
1190  EXPECT_FALSE(IRect::MakeXYWH(10, 30, 19, 20).IsSquare());
1191  EXPECT_TRUE(IRect::MakeMaximum().IsSquare());
1192 }

References impeller::TRect< Scalar >::MakeMaximum(), impeller::TRect< T >::MakeMaximum(), impeller::TRect< T >::MakeXYWH(), and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST() [258/360]

impeller::testing::TEST ( RectTest  ,
MakePointBoundsQuad   
)

Definition at line 1168 of file rect_unittests.cc.

1168  {
1169  Quad quad = {
1170  Point(10, 10),
1171  Point(20, 10),
1172  Point(10, 20),
1173  Point(20, 20),
1174  };
1175  std::optional<Rect> bounds = Rect::MakePointBounds(quad);
1176  EXPECT_TRUE(bounds.has_value());
1177  if (bounds.has_value()) {
1178  EXPECT_TRUE(RectNear(bounds.value(), Rect::MakeLTRB(10, 10, 20, 20)));
1179  }
1180 }

References impeller::TRect< Scalar >::MakeLTRB(), impeller::TRect< Scalar >::MakePointBounds(), and RectNear().

◆ TEST() [259/360]

impeller::testing::TEST ( RectTest  ,
OptIRectIntersection   
)

Definition at line 1846 of file rect_unittests.cc.

1846  {
1847  auto a = IRect::MakeLTRB(0, 0, 110, 110);
1848  auto b = IRect::MakeLTRB(100, 100, 200, 200);
1849  auto c = IRect::MakeLTRB(100, 0, 200, 110);
1850 
1851  // NullOpt, NullOpt
1852  EXPECT_FALSE(IRect::Intersection(std::nullopt, std::nullopt).has_value());
1853  EXPECT_EQ(IRect::Intersection(std::nullopt, std::nullopt), std::nullopt);
1854 
1855  auto test1 = [](const IRect& r) {
1856  // Rect, NullOpt
1857  EXPECT_TRUE(IRect::Intersection(r, std::nullopt).has_value());
1858  EXPECT_EQ(IRect::Intersection(r, std::nullopt).value(), r);
1859 
1860  // OptRect, NullOpt
1861  EXPECT_TRUE(
1862  IRect::Intersection(std::optional(r), std::nullopt).has_value());
1863  EXPECT_EQ(IRect::Intersection(std::optional(r), std::nullopt).value(), r);
1864 
1865  // NullOpt, Rect
1866  EXPECT_TRUE(IRect::Intersection(std::nullopt, r).has_value());
1867  EXPECT_EQ(IRect::Intersection(std::nullopt, r).value(), r);
1868 
1869  // NullOpt, OptRect
1870  EXPECT_TRUE(
1871  IRect::Intersection(std::nullopt, std::optional(r)).has_value());
1872  EXPECT_EQ(IRect::Intersection(std::nullopt, std::optional(r)).value(), r);
1873  };
1874 
1875  test1(a);
1876  test1(b);
1877  test1(c);
1878 
1879  auto test2 = [](const IRect& a, const IRect& b, const IRect& i) {
1880  ASSERT_EQ(a.Intersection(b), i);
1881 
1882  // Rect, OptRect
1883  EXPECT_TRUE(IRect::Intersection(a, std::optional(b)).has_value());
1884  EXPECT_EQ(IRect::Intersection(a, std::optional(b)).value(), i);
1885 
1886  // OptRect, Rect
1887  EXPECT_TRUE(IRect::Intersection(std::optional(a), b).has_value());
1888  EXPECT_EQ(IRect::Intersection(std::optional(a), b).value(), i);
1889 
1890  // OptRect, OptRect
1891  EXPECT_TRUE(
1892  IRect::Intersection(std::optional(a), std::optional(b)).has_value());
1893  EXPECT_EQ(IRect::Intersection(std::optional(a), std::optional(b)).value(),
1894  i);
1895  };
1896 
1897  test2(a, b, IRect::MakeLTRB(100, 100, 110, 110));
1898  test2(a, c, IRect::MakeLTRB(100, 0, 110, 110));
1899  test2(b, c, IRect::MakeLTRB(100, 100, 200, 110));
1900 }

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

◆ TEST() [260/360]

impeller::testing::TEST ( RectTest  ,
OptIRectUnion   
)

Definition at line 1528 of file rect_unittests.cc.

1528  {
1529  auto a = IRect::MakeLTRB(0, 0, 100, 100);
1530  auto b = IRect::MakeLTRB(100, 100, 200, 200);
1531  auto c = IRect::MakeLTRB(100, 0, 200, 100);
1532 
1533  // NullOpt, NullOpt
1534  EXPECT_FALSE(IRect::Union(std::nullopt, std::nullopt).has_value());
1535  EXPECT_EQ(IRect::Union(std::nullopt, std::nullopt), std::nullopt);
1536 
1537  auto test1 = [](const IRect& r) {
1538  // Rect, NullOpt
1539  EXPECT_TRUE(IRect::Union(r, std::nullopt).has_value());
1540  EXPECT_EQ(IRect::Union(r, std::nullopt).value(), r);
1541 
1542  // OptRect, NullOpt
1543  EXPECT_TRUE(IRect::Union(std::optional(r), std::nullopt).has_value());
1544  EXPECT_EQ(IRect::Union(std::optional(r), std::nullopt).value(), r);
1545 
1546  // NullOpt, Rect
1547  EXPECT_TRUE(IRect::Union(std::nullopt, r).has_value());
1548  EXPECT_EQ(IRect::Union(std::nullopt, r).value(), r);
1549 
1550  // NullOpt, OptRect
1551  EXPECT_TRUE(IRect::Union(std::nullopt, std::optional(r)).has_value());
1552  EXPECT_EQ(IRect::Union(std::nullopt, std::optional(r)).value(), r);
1553  };
1554 
1555  test1(a);
1556  test1(b);
1557  test1(c);
1558 
1559  auto test2 = [](const IRect& a, const IRect& b, const IRect& u) {
1560  ASSERT_EQ(a.Union(b), u);
1561 
1562  // Rect, OptRect
1563  EXPECT_TRUE(IRect::Union(a, std::optional(b)).has_value());
1564  EXPECT_EQ(IRect::Union(a, std::optional(b)).value(), u);
1565 
1566  // OptRect, Rect
1567  EXPECT_TRUE(IRect::Union(std::optional(a), b).has_value());
1568  EXPECT_EQ(IRect::Union(std::optional(a), b).value(), u);
1569 
1570  // OptRect, OptRect
1571  EXPECT_TRUE(IRect::Union(std::optional(a), std::optional(b)).has_value());
1572  EXPECT_EQ(IRect::Union(std::optional(a), std::optional(b)).value(), u);
1573  };
1574 
1575  test2(a, b, IRect::MakeLTRB(0, 0, 200, 200));
1576  test2(a, c, IRect::MakeLTRB(0, 0, 200, 100));
1577  test2(b, c, IRect::MakeLTRB(100, 0, 200, 200));
1578 }

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

◆ TEST() [261/360]

impeller::testing::TEST ( RectTest  ,
OptRectIntersection   
)

Definition at line 1697 of file rect_unittests.cc.

1697  {
1698  auto a = Rect::MakeLTRB(0, 0, 110, 110);
1699  auto b = Rect::MakeLTRB(100, 100, 200, 200);
1700  auto c = Rect::MakeLTRB(100, 0, 200, 110);
1701 
1702  // NullOpt, NullOpt
1703  EXPECT_FALSE(Rect::Intersection(std::nullopt, std::nullopt).has_value());
1704  EXPECT_EQ(Rect::Intersection(std::nullopt, std::nullopt), std::nullopt);
1705 
1706  auto test1 = [](const Rect& r) {
1707  // Rect, NullOpt
1708  EXPECT_TRUE(Rect::Intersection(r, std::nullopt).has_value());
1709  EXPECT_EQ(Rect::Intersection(r, std::nullopt).value(), r);
1710 
1711  // OptRect, NullOpt
1712  EXPECT_TRUE(Rect::Intersection(std::optional(r), std::nullopt).has_value());
1713  EXPECT_EQ(Rect::Intersection(std::optional(r), std::nullopt).value(), r);
1714 
1715  // NullOpt, Rect
1716  EXPECT_TRUE(Rect::Intersection(std::nullopt, r).has_value());
1717  EXPECT_EQ(Rect::Intersection(std::nullopt, r).value(), r);
1718 
1719  // NullOpt, OptRect
1720  EXPECT_TRUE(Rect::Intersection(std::nullopt, std::optional(r)).has_value());
1721  EXPECT_EQ(Rect::Intersection(std::nullopt, std::optional(r)).value(), r);
1722  };
1723 
1724  test1(a);
1725  test1(b);
1726  test1(c);
1727 
1728  auto test2 = [](const Rect& a, const Rect& b, const Rect& i) {
1729  ASSERT_EQ(a.Intersection(b), i);
1730 
1731  // Rect, OptRect
1732  EXPECT_TRUE(Rect::Intersection(a, std::optional(b)).has_value());
1733  EXPECT_EQ(Rect::Intersection(a, std::optional(b)).value(), i);
1734 
1735  // OptRect, Rect
1736  EXPECT_TRUE(Rect::Intersection(std::optional(a), b).has_value());
1737  EXPECT_EQ(Rect::Intersection(std::optional(a), b).value(), i);
1738 
1739  // OptRect, OptRect
1740  EXPECT_TRUE(
1741  Rect::Intersection(std::optional(a), std::optional(b)).has_value());
1742  EXPECT_EQ(Rect::Intersection(std::optional(a), std::optional(b)).value(),
1743  i);
1744  };
1745 
1746  test2(a, b, Rect::MakeLTRB(100, 100, 110, 110));
1747  test2(a, c, Rect::MakeLTRB(100, 0, 110, 110));
1748  test2(b, c, Rect::MakeLTRB(100, 100, 200, 110));
1749 }

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

◆ TEST() [262/360]

impeller::testing::TEST ( RectTest  ,
OptRectUnion   
)

Definition at line 1404 of file rect_unittests.cc.

1404  {
1405  auto a = Rect::MakeLTRB(0, 0, 100, 100);
1406  auto b = Rect::MakeLTRB(100, 100, 200, 200);
1407  auto c = Rect::MakeLTRB(100, 0, 200, 100);
1408 
1409  // NullOpt, NullOpt
1410  EXPECT_FALSE(Rect::Union(std::nullopt, std::nullopt).has_value());
1411  EXPECT_EQ(Rect::Union(std::nullopt, std::nullopt), std::nullopt);
1412 
1413  auto test1 = [](const Rect& r) {
1414  // Rect, NullOpt
1415  EXPECT_TRUE(Rect::Union(r, std::nullopt).has_value());
1416  EXPECT_EQ(Rect::Union(r, std::nullopt).value(), r);
1417 
1418  // OptRect, NullOpt
1419  EXPECT_TRUE(Rect::Union(std::optional(r), std::nullopt).has_value());
1420  EXPECT_EQ(Rect::Union(std::optional(r), std::nullopt).value(), r);
1421 
1422  // NullOpt, Rect
1423  EXPECT_TRUE(Rect::Union(std::nullopt, r).has_value());
1424  EXPECT_EQ(Rect::Union(std::nullopt, r).value(), r);
1425 
1426  // NullOpt, OptRect
1427  EXPECT_TRUE(Rect::Union(std::nullopt, std::optional(r)).has_value());
1428  EXPECT_EQ(Rect::Union(std::nullopt, std::optional(r)).value(), r);
1429  };
1430 
1431  test1(a);
1432  test1(b);
1433  test1(c);
1434 
1435  auto test2 = [](const Rect& a, const Rect& b, const Rect& u) {
1436  ASSERT_EQ(a.Union(b), u);
1437 
1438  // Rect, OptRect
1439  EXPECT_TRUE(Rect::Union(a, std::optional(b)).has_value());
1440  EXPECT_EQ(Rect::Union(a, std::optional(b)).value(), u);
1441 
1442  // OptRect, Rect
1443  EXPECT_TRUE(Rect::Union(std::optional(a), b).has_value());
1444  EXPECT_EQ(Rect::Union(std::optional(a), b).value(), u);
1445 
1446  // OptRect, OptRect
1447  EXPECT_TRUE(Rect::Union(std::optional(a), std::optional(b)).has_value());
1448  EXPECT_EQ(Rect::Union(std::optional(a), std::optional(b)).value(), u);
1449  };
1450 
1451  test2(a, b, Rect::MakeLTRB(0, 0, 200, 200));
1452  test2(a, c, Rect::MakeLTRB(0, 0, 200, 100));
1453  test2(b, c, Rect::MakeLTRB(100, 0, 200, 200));
1454 }

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

◆ TEST() [263/360]

impeller::testing::TEST ( RectTest  ,
RectArea   
)

Definition at line 971 of file rect_unittests.cc.

971  {
972  EXPECT_EQ(Rect::MakeXYWH(0, 0, 100, 200).Area(), 20000);
973  EXPECT_EQ(Rect::MakeXYWH(10, 20, 100, 200).Area(), 20000);
974  EXPECT_EQ(Rect::MakeXYWH(0, 0, 200, 100).Area(), 20000);
975  EXPECT_EQ(Rect::MakeXYWH(10, 20, 200, 100).Area(), 20000);
976  EXPECT_EQ(Rect::MakeXYWH(0, 0, 100, 100).Area(), 10000);
977  EXPECT_EQ(Rect::MakeXYWH(10, 20, 100, 100).Area(), 10000);
978 }

References impeller::TRect< Scalar >::MakeXYWH().

◆ TEST() [264/360]

impeller::testing::TEST ( RectTest  ,
RectContainsInclusivePoint   
)

Definition at line 2262 of file rect_unittests.cc.

2262  {
2263  auto check_nans = [](const Rect& rect, const Point& point,
2264  const std::string& label) {
2265  ASSERT_TRUE(rect.IsFinite()) << label;
2266  ASSERT_TRUE(point.IsFinite()) << label;
2267 
2268  for (int i = 1; i < 16; i++) {
2269  EXPECT_FALSE(swap_nan(rect, i).ContainsInclusive(point))
2270  << label << ", index = " << i;
2271  for (int j = 1; j < 4; j++) {
2272  EXPECT_FALSE(swap_nan(rect, i).ContainsInclusive(swap_nan(point, j)))
2273  << label << ", indices = " << i << ", " << j;
2274  }
2275  }
2276  };
2277 
2278  auto check_empty_flips = [](const Rect& rect, const Point& point,
2279  const std::string& label) {
2280  ASSERT_FALSE(rect.IsEmpty());
2281 
2282  EXPECT_FALSE(flip_lr(rect).ContainsInclusive(point)) << label;
2283  EXPECT_FALSE(flip_tb(rect).ContainsInclusive(point)) << label;
2284  EXPECT_FALSE(flip_lrtb(rect).ContainsInclusive(point)) << label;
2285  };
2286 
2287  auto test_inside = [&check_nans, &check_empty_flips](const Rect& rect,
2288  const Point& point) {
2289  ASSERT_FALSE(rect.IsEmpty()) << rect;
2290 
2291  std::stringstream stream;
2292  stream << rect << " contains " << point;
2293  auto label = stream.str();
2294 
2295  EXPECT_TRUE(rect.ContainsInclusive(point)) << label;
2296  check_empty_flips(rect, point, label);
2297  check_nans(rect, point, label);
2298  };
2299 
2300  auto test_outside = [&check_nans, &check_empty_flips](const Rect& rect,
2301  const Point& point) {
2302  ASSERT_FALSE(rect.IsEmpty()) << rect;
2303 
2304  std::stringstream stream;
2305  stream << rect << " contains " << point;
2306  auto label = stream.str();
2307 
2308  EXPECT_FALSE(rect.ContainsInclusive(point)) << label;
2309  check_empty_flips(rect, point, label);
2310  check_nans(rect, point, label);
2311  };
2312 
2313  {
2314  // Origin is inclusive
2315  auto r = Rect::MakeXYWH(100, 100, 100, 100);
2316  auto p = Point(100, 100);
2317 
2318  test_inside(r, p);
2319  }
2320  {
2321  // Size is inclusive
2322  auto r = Rect::MakeXYWH(100, 100, 100, 100);
2323  auto p = Point(200, 200);
2324 
2325  test_inside(r, p);
2326  }
2327  {
2328  // Size + epsilon is exclusive
2329  auto r = Rect::MakeXYWH(100, 100, 100, 100);
2330  auto p = Point(200 + kEhCloseEnough, 200 + kEhCloseEnough);
2331 
2332  test_outside(r, p);
2333  }
2334  {
2335  auto r = Rect::MakeXYWH(100, 100, 100, 100);
2336  auto p = Point(99, 99);
2337 
2338  test_outside(r, p);
2339  }
2340  {
2341  auto r = Rect::MakeXYWH(100, 100, 100, 100);
2342  auto p = Point(199, 199);
2343 
2344  test_inside(r, p);
2345  }
2346 
2347  {
2348  auto r = Rect::MakeMaximum();
2349  auto p = Point(199, 199);
2350 
2351  test_inside(r, p);
2352  }
2353 }

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

impeller::testing::TEST ( RectTest  ,
RectContainsPoint   
)

Definition at line 2107 of file rect_unittests.cc.

2107  {
2108  auto check_nans = [](const Rect& rect, const Point& point,
2109  const std::string& label) {
2110  ASSERT_TRUE(rect.IsFinite()) << label;
2111  ASSERT_TRUE(point.IsFinite()) << label;
2112 
2113  for (int i = 1; i < 16; i++) {
2114  EXPECT_FALSE(swap_nan(rect, i).Contains(point))
2115  << label << ", index = " << i;
2116  for (int j = 1; j < 4; j++) {
2117  EXPECT_FALSE(swap_nan(rect, i).Contains(swap_nan(point, j)))
2118  << label << ", indices = " << i << ", " << j;
2119  }
2120  }
2121  };
2122 
2123  auto check_empty_flips = [](const Rect& rect, const Point& point,
2124  const std::string& label) {
2125  ASSERT_FALSE(rect.IsEmpty());
2126 
2127  EXPECT_FALSE(flip_lr(rect).Contains(point)) << label;
2128  EXPECT_FALSE(flip_tb(rect).Contains(point)) << label;
2129  EXPECT_FALSE(flip_lrtb(rect).Contains(point)) << label;
2130  };
2131 
2132  auto test_inside = [&check_nans, &check_empty_flips](const Rect& rect,
2133  const Point& point) {
2134  ASSERT_FALSE(rect.IsEmpty()) << rect;
2135 
2136  std::stringstream stream;
2137  stream << rect << " contains " << point;
2138  auto label = stream.str();
2139 
2140  EXPECT_TRUE(rect.Contains(point)) << label;
2141  check_empty_flips(rect, point, label);
2142  check_nans(rect, point, label);
2143  };
2144 
2145  auto test_outside = [&check_nans, &check_empty_flips](const Rect& rect,
2146  const Point& point) {
2147  ASSERT_FALSE(rect.IsEmpty()) << rect;
2148 
2149  std::stringstream stream;
2150  stream << rect << " contains " << point;
2151  auto label = stream.str();
2152 
2153  EXPECT_FALSE(rect.Contains(point)) << label;
2154  check_empty_flips(rect, point, label);
2155  check_nans(rect, point, label);
2156  };
2157 
2158  {
2159  // Origin is inclusive
2160  auto r = Rect::MakeXYWH(100, 100, 100, 100);
2161  auto p = Point(100, 100);
2162 
2163  test_inside(r, p);
2164  }
2165  {
2166  // Size is exclusive
2167  auto r = Rect::MakeXYWH(100, 100, 100, 100);
2168  auto p = Point(200, 200);
2169 
2170  test_outside(r, p);
2171  }
2172  {
2173  auto r = Rect::MakeXYWH(100, 100, 100, 100);
2174  auto p = Point(99, 99);
2175 
2176  test_outside(r, p);
2177  }
2178  {
2179  auto r = Rect::MakeXYWH(100, 100, 100, 100);
2180  auto p = Point(199, 199);
2181 
2182  test_inside(r, p);
2183  }
2184 
2185  {
2186  auto r = Rect::MakeMaximum();
2187  auto p = Point(199, 199);
2188 
2189  test_inside(r, p);
2190  }
2191 }

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

impeller::testing::TEST ( RectTest  ,
RectContainsRect   
)

Definition at line 2431 of file rect_unittests.cc.

2431  {
2432  auto check_nans = [](const Rect& a, const Rect& b, const std::string& label) {
2433  ASSERT_TRUE(a.IsFinite()) << label;
2434  ASSERT_TRUE(b.IsFinite()) << label;
2435  ASSERT_FALSE(a.IsEmpty());
2436 
2437  for (int i = 1; i < 16; i++) {
2438  // NaN in a produces false
2439  EXPECT_FALSE(swap_nan(a, i).Contains(b)) << label << ", index = " << i;
2440  // NaN in b produces false
2441  EXPECT_TRUE(a.Contains(swap_nan(b, i))) << label << ", index = " << i;
2442  // NaN in both is false
2443  for (int j = 1; j < 16; j++) {
2444  EXPECT_FALSE(swap_nan(a, i).Contains(swap_nan(b, j)))
2445  << label << ", indices = " << i << ", " << j;
2446  }
2447  }
2448  };
2449 
2450  auto check_empty_flips = [](const Rect& a, const Rect& b,
2451  const std::string& label) {
2452  ASSERT_FALSE(a.IsEmpty());
2453  // test b rects are allowed to have 0 w/h, but not be backwards
2454  ASSERT_FALSE(b.GetLeft() > b.GetRight() || b.GetTop() > b.GetBottom());
2455 
2456  // unflipped a vs flipped (empty) b yields false
2457  EXPECT_TRUE(a.Contains(flip_lr(b))) << label;
2458  EXPECT_TRUE(a.Contains(flip_tb(b))) << label;
2459  EXPECT_TRUE(a.Contains(flip_lrtb(b))) << label;
2460 
2461  // flipped (empty) a vs unflipped b yields false
2462  EXPECT_FALSE(flip_lr(a).Contains(b)) << label;
2463  EXPECT_FALSE(flip_tb(a).Contains(b)) << label;
2464  EXPECT_FALSE(flip_lrtb(a).Contains(b)) << label;
2465 
2466  // flipped (empty) a vs flipped (empty) b yields empty
2467  EXPECT_FALSE(flip_lr(a).Contains(flip_lr(b))) << label;
2468  EXPECT_FALSE(flip_tb(a).Contains(flip_tb(b))) << label;
2469  EXPECT_FALSE(flip_lrtb(a).Contains(flip_lrtb(b))) << label;
2470  };
2471 
2472  auto test_inside = [&check_nans, &check_empty_flips](const Rect& a,
2473  const Rect& b) {
2474  ASSERT_FALSE(a.IsEmpty()) << a;
2475  // test b rects are allowed to have 0 w/h, but not be backwards
2476  ASSERT_FALSE(b.GetLeft() > b.GetRight() || b.GetTop() > b.GetBottom());
2477 
2478  std::stringstream stream;
2479  stream << a << " contains " << b;
2480  auto label = stream.str();
2481 
2482  EXPECT_TRUE(a.Contains(b)) << label;
2483  check_empty_flips(a, b, label);
2484  check_nans(a, b, label);
2485  };
2486 
2487  auto test_not_inside = [&check_nans, &check_empty_flips](const Rect& a,
2488  const Rect& b) {
2489  ASSERT_FALSE(a.IsEmpty()) << a;
2490  // If b was empty, it would be contained and should not be tested with
2491  // this function - use |test_inside| instead.
2492  ASSERT_FALSE(b.IsEmpty()) << b;
2493 
2494  std::stringstream stream;
2495  stream << a << " contains " << b;
2496  auto label = stream.str();
2497 
2498  EXPECT_FALSE(a.Contains(b)) << label;
2499  check_empty_flips(a, b, label);
2500  check_nans(a, b, label);
2501  };
2502 
2503  {
2504  auto a = Rect::MakeXYWH(100, 100, 100, 100);
2505 
2506  test_inside(a, a);
2507  }
2508  {
2509  auto a = Rect::MakeXYWH(100, 100, 100, 100);
2510  auto b = Rect::MakeXYWH(0, 0, 0, 0);
2511 
2512  test_inside(a, b);
2513  }
2514  {
2515  auto a = Rect::MakeXYWH(100, 100, 100, 100);
2516  auto b = Rect::MakeXYWH(150, 150, 20, 20);
2517 
2518  test_inside(a, b);
2519  }
2520  {
2521  auto a = Rect::MakeXYWH(100, 100, 100, 100);
2522  auto b = Rect::MakeXYWH(150, 150, 100, 100);
2523 
2524  test_not_inside(a, b);
2525  }
2526  {
2527  auto a = Rect::MakeXYWH(100, 100, 100, 100);
2528  auto b = Rect::MakeXYWH(50, 50, 100, 100);
2529 
2530  test_not_inside(a, b);
2531  }
2532  {
2533  auto a = Rect::MakeXYWH(100, 100, 100, 100);
2534  auto b = Rect::MakeXYWH(0, 0, 300, 300);
2535 
2536  test_not_inside(a, b);
2537  }
2538  {
2539  auto a = Rect::MakeMaximum();
2540  auto b = Rect::MakeXYWH(0, 0, 300, 300);
2541 
2542  test_inside(a, b);
2543  }
2544 }

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

impeller::testing::TEST ( RectTest  ,
RectCopy   
)

Definition at line 623 of file rect_unittests.cc.

623  {
624  // Using fractional-power-of-2 friendly values for equality tests
625  Rect rect = Rect::MakeLTRB(5.125f, 10.25f, 20.625f, 25.375f);
626  Rect copy = rect;
627 
628  EXPECT_EQ(rect, copy);
629  EXPECT_EQ(copy.GetLeft(), 5.125f);
630  EXPECT_EQ(copy.GetTop(), 10.25f);
631  EXPECT_EQ(copy.GetRight(), 20.625f);
632  EXPECT_EQ(copy.GetBottom(), 25.375f);
633  EXPECT_EQ(copy.GetX(), 5.125f);
634  EXPECT_EQ(copy.GetY(), 10.25f);
635  EXPECT_EQ(copy.GetWidth(), 15.5f);
636  EXPECT_EQ(copy.GetHeight(), 15.125f);
637  EXPECT_FALSE(copy.IsEmpty());
638  EXPECT_TRUE(copy.IsFinite());
639 }

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

impeller::testing::TEST ( RectTest  ,
RectCutOut   
)

Definition at line 2639 of file rect_unittests.cc.

2639  {
2640  Rect cull_rect = Rect::MakeLTRB(20, 20, 40, 40);
2641 
2642  auto check_nans = [&cull_rect](const Rect& diff_rect,
2643  const std::string& label) {
2644  EXPECT_TRUE(cull_rect.IsFinite()) << label;
2645  EXPECT_TRUE(diff_rect.IsFinite()) << label;
2646 
2647  for (int i = 1; i < 16; i++) {
2648  // NaN in cull_rect produces empty
2649  EXPECT_FALSE(swap_nan(cull_rect, i).Cutout(diff_rect).has_value())
2650  << label << ", index " << i;
2651  EXPECT_EQ(swap_nan(cull_rect, i).CutoutOrEmpty(diff_rect), Rect())
2652  << label << ", index " << i;
2653 
2654  // NaN in diff_rect is nop
2655  EXPECT_TRUE(cull_rect.Cutout(swap_nan(diff_rect, i)).has_value())
2656  << label << ", index " << i;
2657  EXPECT_EQ(cull_rect.CutoutOrEmpty(swap_nan(diff_rect, i)), cull_rect)
2658  << label << ", index " << i;
2659 
2660  for (int j = 1; j < 16; j++) {
2661  // NaN in both is also empty
2662  EXPECT_FALSE(
2663  swap_nan(cull_rect, i).Cutout(swap_nan(diff_rect, j)).has_value())
2664  << label << ", indices " << i << ", " << j;
2665  EXPECT_EQ(swap_nan(cull_rect, i).CutoutOrEmpty(swap_nan(diff_rect, j)),
2666  Rect())
2667  << label << ", indices " << i << ", " << j;
2668  }
2669  }
2670  };
2671 
2672  auto check_empty_flips = [&cull_rect](const Rect& diff_rect,
2673  const std::string& label) {
2674  EXPECT_FALSE(cull_rect.IsEmpty()) << label;
2675  EXPECT_FALSE(diff_rect.IsEmpty()) << label;
2676 
2677  // unflipped cull_rect vs flipped(empty) diff_rect
2678  // == cull_rect
2679  EXPECT_TRUE(cull_rect.Cutout(flip_lr(diff_rect)).has_value()) << label;
2680  EXPECT_EQ(cull_rect.Cutout(flip_lr(diff_rect)), cull_rect) << label;
2681  EXPECT_TRUE(cull_rect.Cutout(flip_tb(diff_rect)).has_value()) << label;
2682  EXPECT_EQ(cull_rect.Cutout(flip_tb(diff_rect)), cull_rect) << label;
2683  EXPECT_TRUE(cull_rect.Cutout(flip_lrtb(diff_rect)).has_value()) << label;
2684  EXPECT_EQ(cull_rect.Cutout(flip_lrtb(diff_rect)), cull_rect) << label;
2685 
2686  // flipped(empty) cull_rect vs unflipped diff_rect
2687  // == empty
2688  EXPECT_FALSE(flip_lr(cull_rect).Cutout(diff_rect).has_value()) << label;
2689  EXPECT_EQ(flip_lr(cull_rect).CutoutOrEmpty(diff_rect), Rect()) << label;
2690  EXPECT_FALSE(flip_tb(cull_rect).Cutout(diff_rect).has_value()) << label;
2691  EXPECT_EQ(flip_tb(cull_rect).CutoutOrEmpty(diff_rect), Rect()) << label;
2692  EXPECT_FALSE(flip_lrtb(cull_rect).Cutout(diff_rect).has_value()) << label;
2693  EXPECT_EQ(flip_lrtb(cull_rect).CutoutOrEmpty(diff_rect), Rect()) << label;
2694 
2695  // flipped(empty) cull_rect vs flipped(empty) diff_rect
2696  // == empty
2697  EXPECT_FALSE(flip_lr(cull_rect).Cutout(flip_lr(diff_rect)).has_value())
2698  << label;
2699  EXPECT_EQ(flip_lr(cull_rect).CutoutOrEmpty(flip_lr(diff_rect)), Rect())
2700  << label;
2701  EXPECT_FALSE(flip_tb(cull_rect).Cutout(flip_tb(diff_rect)).has_value())
2702  << label;
2703  EXPECT_EQ(flip_tb(cull_rect).CutoutOrEmpty(flip_tb(diff_rect)), Rect())
2704  << label;
2705  EXPECT_FALSE(flip_lrtb(cull_rect).Cutout(flip_lrtb(diff_rect)).has_value())
2706  << label;
2707  EXPECT_EQ(flip_lrtb(cull_rect).CutoutOrEmpty(flip_lrtb(diff_rect)), Rect())
2708  << label;
2709  };
2710 
2711  auto non_reducing = [&cull_rect, &check_empty_flips, &check_nans](
2712  const Rect& diff_rect, const std::string& label) {
2713  EXPECT_EQ(cull_rect.Cutout(diff_rect), cull_rect) << label;
2714  EXPECT_EQ(cull_rect.CutoutOrEmpty(diff_rect), cull_rect) << label;
2715  check_empty_flips(diff_rect, label);
2716  check_nans(diff_rect, label);
2717  };
2718 
2719  auto reducing = [&cull_rect, &check_empty_flips, &check_nans](
2720  const Rect& diff_rect, const Rect& result_rect,
2721  const std::string& label) {
2722  EXPECT_TRUE(!result_rect.IsEmpty());
2723  EXPECT_EQ(cull_rect.Cutout(diff_rect), result_rect) << label;
2724  EXPECT_EQ(cull_rect.CutoutOrEmpty(diff_rect), result_rect) << label;
2725  check_empty_flips(diff_rect, label);
2726  check_nans(diff_rect, label);
2727  };
2728 
2729  auto emptying = [&cull_rect, &check_empty_flips, &check_nans](
2730  const Rect& diff_rect, const std::string& label) {
2731  EXPECT_FALSE(cull_rect.Cutout(diff_rect).has_value()) << label;
2732  EXPECT_EQ(cull_rect.CutoutOrEmpty(diff_rect), Rect()) << label;
2733  check_empty_flips(diff_rect, label);
2734  check_nans(diff_rect, label);
2735  };
2736 
2737  // Skim the corners and edge
2738  non_reducing(Rect::MakeLTRB(10, 10, 20, 20), "outside UL corner");
2739  non_reducing(Rect::MakeLTRB(20, 10, 40, 20), "Above");
2740  non_reducing(Rect::MakeLTRB(40, 10, 50, 20), "outside UR corner");
2741  non_reducing(Rect::MakeLTRB(40, 20, 50, 40), "Right");
2742  non_reducing(Rect::MakeLTRB(40, 40, 50, 50), "outside LR corner");
2743  non_reducing(Rect::MakeLTRB(20, 40, 40, 50), "Below");
2744  non_reducing(Rect::MakeLTRB(10, 40, 20, 50), "outside LR corner");
2745  non_reducing(Rect::MakeLTRB(10, 20, 20, 40), "Left");
2746 
2747  // Overlap corners
2748  non_reducing(Rect::MakeLTRB(15, 15, 25, 25), "covering UL corner");
2749  non_reducing(Rect::MakeLTRB(35, 15, 45, 25), "covering UR corner");
2750  non_reducing(Rect::MakeLTRB(35, 35, 45, 45), "covering LR corner");
2751  non_reducing(Rect::MakeLTRB(15, 35, 25, 45), "covering LL corner");
2752 
2753  // Overlap edges, but not across an entire side
2754  non_reducing(Rect::MakeLTRB(20, 15, 39, 25), "Top edge left-biased");
2755  non_reducing(Rect::MakeLTRB(21, 15, 40, 25), "Top edge, right biased");
2756  non_reducing(Rect::MakeLTRB(35, 20, 45, 39), "Right edge, top-biased");
2757  non_reducing(Rect::MakeLTRB(35, 21, 45, 40), "Right edge, bottom-biased");
2758  non_reducing(Rect::MakeLTRB(20, 35, 39, 45), "Bottom edge, left-biased");
2759  non_reducing(Rect::MakeLTRB(21, 35, 40, 45), "Bottom edge, right-biased");
2760  non_reducing(Rect::MakeLTRB(15, 20, 25, 39), "Left edge, top-biased");
2761  non_reducing(Rect::MakeLTRB(15, 21, 25, 40), "Left edge, bottom-biased");
2762 
2763  // Slice all the way through the middle
2764  non_reducing(Rect::MakeLTRB(25, 15, 35, 45), "Vertical interior slice");
2765  non_reducing(Rect::MakeLTRB(15, 25, 45, 35), "Horizontal interior slice");
2766 
2767  // Slice off each edge
2768  reducing(Rect::MakeLTRB(20, 15, 40, 25), //
2769  Rect::MakeLTRB(20, 25, 40, 40), //
2770  "Slice off top");
2771  reducing(Rect::MakeLTRB(35, 20, 45, 40), //
2772  Rect::MakeLTRB(20, 20, 35, 40), //
2773  "Slice off right");
2774  reducing(Rect::MakeLTRB(20, 35, 40, 45), //
2775  Rect::MakeLTRB(20, 20, 40, 35), //
2776  "Slice off bottom");
2777  reducing(Rect::MakeLTRB(15, 20, 25, 40), //
2778  Rect::MakeLTRB(25, 20, 40, 40), //
2779  "Slice off left");
2780 
2781  // cull rect contains diff rect
2782  non_reducing(Rect::MakeLTRB(21, 21, 39, 39), "Contained, non-covering");
2783 
2784  // cull rect equals diff rect
2785  emptying(cull_rect, "Perfectly covering");
2786 
2787  // diff rect contains cull rect
2788  emptying(Rect::MakeLTRB(15, 15, 45, 45), "Smothering");
2789 }

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

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

impeller::testing::TEST ( RectTest  ,
RectDirections   
)

Definition at line 2981 of file rect_unittests.cc.

2981  {
2982  auto r = Rect::MakeLTRB(1, 2, 3, 4);
2983 
2984  EXPECT_EQ(r.GetLeft(), 1);
2985  EXPECT_EQ(r.GetTop(), 2);
2986  EXPECT_EQ(r.GetRight(), 3);
2987  EXPECT_EQ(r.GetBottom(), 4);
2988 
2989  EXPECT_POINT_NEAR(r.GetLeftTop(), Point(1, 2));
2990  EXPECT_POINT_NEAR(r.GetRightTop(), Point(3, 2));
2991  EXPECT_POINT_NEAR(r.GetLeftBottom(), Point(1, 4));
2992  EXPECT_POINT_NEAR(r.GetRightBottom(), Point(3, 4));
2993 }

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

◆ TEST() [271/360]

impeller::testing::TEST ( RectTest  ,
RectDoesNotIntersectEmpty   
)

Definition at line 764 of file rect_unittests.cc.

764  {
765  Rect rect = Rect::MakeLTRB(50, 50, 100, 100);
766 
767  auto test = [&rect](Scalar l, Scalar t, Scalar r, Scalar b,
768  const std::string& label) {
769  EXPECT_FALSE(rect.IntersectsWithRect(Rect::MakeLTRB(l, b, r, t)))
770  << label << " with Top/Bottom swapped";
771  EXPECT_FALSE(rect.IntersectsWithRect(Rect::MakeLTRB(r, b, l, t)))
772  << label << " with Left/Right swapped";
773  EXPECT_FALSE(rect.IntersectsWithRect(Rect::MakeLTRB(r, t, l, b)))
774  << label << " with all sides swapped";
775  };
776 
777  test(20, 20, 30, 30, "Above and Left");
778  test(70, 20, 80, 30, "Above");
779  test(120, 20, 130, 30, "Above and Right");
780  test(120, 70, 130, 80, "Right");
781  test(120, 120, 130, 130, "Below and Right");
782  test(70, 120, 80, 130, "Below");
783  test(20, 120, 30, 130, "Below and Left");
784  test(20, 70, 30, 80, "Left");
785 
786  test(70, 70, 80, 80, "Inside");
787 
788  test(40, 70, 60, 80, "Straddling Left");
789  test(70, 40, 80, 60, "Straddling Top");
790  test(90, 70, 110, 80, "Straddling Right");
791  test(70, 90, 80, 110, "Straddling Bottom");
792 }

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

◆ TEST() [272/360]

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

impeller::testing::TEST ( RectTest  ,
RectExpand   
)

Definition at line 1205 of file rect_unittests.cc.

1205  {
1206  auto rect = Rect::MakeLTRB(100, 100, 200, 200);
1207 
1208  // Expand(T amount)
1209  EXPECT_EQ(rect.Expand(10), Rect::MakeLTRB(90, 90, 210, 210));
1210  EXPECT_EQ(rect.Expand(-10), Rect::MakeLTRB(110, 110, 190, 190));
1211 
1212  // Expand(amount, amount)
1213  EXPECT_EQ(rect.Expand(10, 10), Rect::MakeLTRB(90, 90, 210, 210));
1214  EXPECT_EQ(rect.Expand(10, -10), Rect::MakeLTRB(90, 110, 210, 190));
1215  EXPECT_EQ(rect.Expand(-10, 10), Rect::MakeLTRB(110, 90, 190, 210));
1216  EXPECT_EQ(rect.Expand(-10, -10), Rect::MakeLTRB(110, 110, 190, 190));
1217 
1218  // Expand(amount, amount, amount, amount)
1219  EXPECT_EQ(rect.Expand(10, 20, 30, 40), Rect::MakeLTRB(90, 80, 230, 240));
1220  EXPECT_EQ(rect.Expand(-10, 20, 30, 40), Rect::MakeLTRB(110, 80, 230, 240));
1221  EXPECT_EQ(rect.Expand(10, -20, 30, 40), Rect::MakeLTRB(90, 120, 230, 240));
1222  EXPECT_EQ(rect.Expand(10, 20, -30, 40), Rect::MakeLTRB(90, 80, 170, 240));
1223  EXPECT_EQ(rect.Expand(10, 20, 30, -40), Rect::MakeLTRB(90, 80, 230, 160));
1224 
1225  // Expand(Point amount)
1226  EXPECT_EQ(rect.Expand(Point{10, 10}), Rect::MakeLTRB(90, 90, 210, 210));
1227  EXPECT_EQ(rect.Expand(Point{10, -10}), Rect::MakeLTRB(90, 110, 210, 190));
1228  EXPECT_EQ(rect.Expand(Point{-10, 10}), Rect::MakeLTRB(110, 90, 190, 210));
1229  EXPECT_EQ(rect.Expand(Point{-10, -10}), Rect::MakeLTRB(110, 110, 190, 190));
1230 
1231  // Expand(Size amount)
1232  EXPECT_EQ(rect.Expand(Size{10, 10}), Rect::MakeLTRB(90, 90, 210, 210));
1233  EXPECT_EQ(rect.Expand(Size{10, -10}), Rect::MakeLTRB(90, 110, 210, 190));
1234  EXPECT_EQ(rect.Expand(Size{-10, 10}), Rect::MakeLTRB(110, 90, 190, 210));
1235  EXPECT_EQ(rect.Expand(Size{-10, -10}), Rect::MakeLTRB(110, 110, 190, 190));
1236 }

References impeller::TRect< Scalar >::MakeLTRB().

◆ TEST() [274/360]

impeller::testing::TEST ( RectTest  ,
RectFromRect   
)

Definition at line 609 of file rect_unittests.cc.

609  {
610  EXPECT_EQ(Rect(Rect::MakeXYWH(2, 3, 7, 15)),
611  Rect::MakeXYWH(2.0, 3.0, 7.0, 15.0));
612  EXPECT_EQ(Rect(Rect::MakeLTRB(2, 3, 7, 15)),
613  Rect::MakeLTRB(2.0, 3.0, 7.0, 15.0));
614 }

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

◆ TEST() [275/360]

impeller::testing::TEST ( RectTest  ,
RectGetNormalizingTransform   
)

Definition at line 989 of file rect_unittests.cc.

989  {
990  {
991  // Checks for expected matrix values
992 
993  auto r = Rect::MakeXYWH(100, 200, 200, 400);
994 
995  EXPECT_EQ(r.GetNormalizingTransform(),
996  Matrix::MakeScale({0.005, 0.0025, 1.0}) *
997  Matrix::MakeTranslation({-100, -200}));
998  }
999 
1000  {
1001  // Checks for expected transform of points relative to the rect
1002 
1003  auto r = Rect::MakeLTRB(300, 500, 400, 700);
1004  auto m = r.GetNormalizingTransform();
1005 
1006  // The 4 corners of the rect => (0, 0) to (1, 1)
1007  EXPECT_EQ(m * Point(300, 500), Point(0, 0));
1008  EXPECT_EQ(m * Point(400, 500), Point(1, 0));
1009  EXPECT_EQ(m * Point(400, 700), Point(1, 1));
1010  EXPECT_EQ(m * Point(300, 700), Point(0, 1));
1011 
1012  // The center => (0.5, 0.5)
1013  EXPECT_EQ(m * Point(350, 600), Point(0.5, 0.5));
1014 
1015  // Outside the 4 corners => (-1, -1) to (2, 2)
1016  EXPECT_EQ(m * Point(200, 300), Point(-1, -1));
1017  EXPECT_EQ(m * Point(500, 300), Point(2, -1));
1018  EXPECT_EQ(m * Point(500, 900), Point(2, 2));
1019  EXPECT_EQ(m * Point(200, 900), Point(-1, 2));
1020  }
1021 
1022  {
1023  // Checks for behavior with empty rects
1024 
1025  auto zero = Matrix::MakeScale({0.0, 0.0, 1.0});
1026 
1027  // Empty for width and/or height == 0
1028  EXPECT_EQ(Rect::MakeXYWH(10, 10, 0, 10).GetNormalizingTransform(), zero);
1029  EXPECT_EQ(Rect::MakeXYWH(10, 10, 10, 0).GetNormalizingTransform(), zero);
1030  EXPECT_EQ(Rect::MakeXYWH(10, 10, 0, 0).GetNormalizingTransform(), zero);
1031 
1032  // Empty for width and/or height < 0
1033  EXPECT_EQ(Rect::MakeXYWH(10, 10, -1, 10).GetNormalizingTransform(), zero);
1034  EXPECT_EQ(Rect::MakeXYWH(10, 10, 10, -1).GetNormalizingTransform(), zero);
1035  EXPECT_EQ(Rect::MakeXYWH(10, 10, -1, -1).GetNormalizingTransform(), zero);
1036  }
1037 
1038  {
1039  // Checks for behavior with non-finite rects
1040 
1041  auto z = Matrix::MakeScale({0.0, 0.0, 1.0});
1042  auto nan = std::numeric_limits<Scalar>::quiet_NaN();
1043  auto inf = std::numeric_limits<Scalar>::infinity();
1044 
1045  // Non-finite for width and/or height == nan
1046  EXPECT_EQ(Rect::MakeXYWH(10, 10, nan, 10).GetNormalizingTransform(), z);
1047  EXPECT_EQ(Rect::MakeXYWH(10, 10, 10, nan).GetNormalizingTransform(), z);
1048  EXPECT_EQ(Rect::MakeXYWH(10, 10, nan, nan).GetNormalizingTransform(), z);
1049 
1050  // Non-finite for width and/or height == inf
1051  EXPECT_EQ(Rect::MakeXYWH(10, 10, inf, 10).GetNormalizingTransform(), z);
1052  EXPECT_EQ(Rect::MakeXYWH(10, 10, 10, inf).GetNormalizingTransform(), z);
1053  EXPECT_EQ(Rect::MakeXYWH(10, 10, inf, inf).GetNormalizingTransform(), z);
1054 
1055  // Non-finite for width and/or height == -inf
1056  EXPECT_EQ(Rect::MakeXYWH(10, 10, -inf, 10).GetNormalizingTransform(), z);
1057  EXPECT_EQ(Rect::MakeXYWH(10, 10, 10, -inf).GetNormalizingTransform(), z);
1058  EXPECT_EQ(Rect::MakeXYWH(10, 10, -inf, -inf).GetNormalizingTransform(), z);
1059 
1060  // Non-finite for origin X and/or Y == nan
1061  EXPECT_EQ(Rect::MakeXYWH(nan, 10, 10, 10).GetNormalizingTransform(), z);
1062  EXPECT_EQ(Rect::MakeXYWH(10, nan, 10, 10).GetNormalizingTransform(), z);
1063  EXPECT_EQ(Rect::MakeXYWH(nan, nan, 10, 10).GetNormalizingTransform(), z);
1064 
1065  // Non-finite for origin X and/or Y == inf
1066  EXPECT_EQ(Rect::MakeXYWH(inf, 10, 10, 10).GetNormalizingTransform(), z);
1067  EXPECT_EQ(Rect::MakeXYWH(10, inf, 10, 10).GetNormalizingTransform(), z);
1068  EXPECT_EQ(Rect::MakeXYWH(inf, inf, 10, 10).GetNormalizingTransform(), z);
1069 
1070  // Non-finite for origin X and/or Y == -inf
1071  EXPECT_EQ(Rect::MakeXYWH(-inf, 10, 10, 10).GetNormalizingTransform(), z);
1072  EXPECT_EQ(Rect::MakeXYWH(10, -inf, 10, 10).GetNormalizingTransform(), z);
1073  EXPECT_EQ(Rect::MakeXYWH(-inf, -inf, 10, 10).GetNormalizingTransform(), z);
1074  }
1075 }

References impeller::TRect< Scalar >::MakeLTRB(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeTranslation(), and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST() [276/360]

impeller::testing::TEST ( RectTest  ,
RectGetPoints   
)

Definition at line 2910 of file rect_unittests.cc.

2910  {
2911  {
2912  Rect r = Rect::MakeXYWH(100, 200, 300, 400);
2913  auto points = r.GetPoints();
2914  EXPECT_POINT_NEAR(points[0], Point(100, 200));
2915  EXPECT_POINT_NEAR(points[1], Point(400, 200));
2916  EXPECT_POINT_NEAR(points[2], Point(100, 600));
2917  EXPECT_POINT_NEAR(points[3], Point(400, 600));
2918  }
2919 
2920  {
2921  Rect r = Rect::MakeMaximum();
2922  auto points = r.GetPoints();
2923  EXPECT_EQ(points[0], Point(std::numeric_limits<float>::lowest(),
2924  std::numeric_limits<float>::lowest()));
2925  EXPECT_EQ(points[1], Point(std::numeric_limits<float>::max(),
2926  std::numeric_limits<float>::lowest()));
2927  EXPECT_EQ(points[2], Point(std::numeric_limits<float>::lowest(),
2928  std::numeric_limits<float>::max()));
2929  EXPECT_EQ(points[3], Point(std::numeric_limits<float>::max(),
2930  std::numeric_limits<float>::max()));
2931  }
2932 }

References EXPECT_POINT_NEAR, impeller::TRect< T >::GetPoints(), impeller::TRect< Scalar >::MakeMaximum(), and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST() [277/360]

impeller::testing::TEST ( RectTest  ,
RectGetPositive   
)

Definition at line 2967 of file rect_unittests.cc.

2967  {
2968  {
2969  Rect r = Rect::MakeXYWH(100, 200, 300, 400);
2970  auto actual = r.GetPositive();
2971  EXPECT_RECT_NEAR(r, actual);
2972  }
2973  {
2974  Rect r = Rect::MakeXYWH(100, 200, -100, -100);
2975  auto actual = r.GetPositive();
2976  Rect expected = Rect::MakeXYWH(0, 100, 100, 100);
2977  EXPECT_RECT_NEAR(expected, actual);
2978  }
2979 }

References EXPECT_RECT_NEAR, impeller::TRect< T >::GetPositive(), and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST() [278/360]

impeller::testing::TEST ( RectTest  ,
RectGetTransformedPoints   
)

Definition at line 2941 of file rect_unittests.cc.

2941  {
2942  Rect r = Rect::MakeXYWH(100, 200, 300, 400);
2943  auto points = r.GetTransformedPoints(Matrix::MakeTranslation({10, 20}));
2944  EXPECT_POINT_NEAR(points[0], Point(110, 220));
2945  EXPECT_POINT_NEAR(points[1], Point(410, 220));
2946  EXPECT_POINT_NEAR(points[2], Point(110, 620));
2947  EXPECT_POINT_NEAR(points[3], Point(410, 620));
2948 }

References EXPECT_POINT_NEAR, impeller::TRect< T >::GetTransformedPoints(), impeller::Matrix::MakeTranslation(), and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST() [279/360]

impeller::testing::TEST ( RectTest  ,
RectIntersection   
)

Definition at line 1580 of file rect_unittests.cc.

1580  {
1581  auto check_nans = [](const Rect& a, const Rect& b, const std::string& label) {
1582  ASSERT_TRUE(a.IsFinite()) << label;
1583  ASSERT_TRUE(b.IsFinite()) << label;
1584 
1585  for (int i = 1; i < 16; i++) {
1586  // NaN in a produces empty
1587  EXPECT_FALSE(swap_nan(a, i).Intersection(b).has_value())
1588  << label << ", index = " << i;
1589  // NaN in b produces empty
1590  EXPECT_FALSE(a.Intersection(swap_nan(b, i)).has_value())
1591  << label << ", index = " << i;
1592  // NaN in both is empty
1593  for (int j = 1; j < 16; j++) {
1594  EXPECT_FALSE(swap_nan(a, i).Intersection(swap_nan(b, j)).has_value())
1595  << label << ", indices = " << i << ", " << j;
1596  }
1597  }
1598  };
1599 
1600  auto check_empty_flips = [](const Rect& a, const Rect& b,
1601  const std::string& label) {
1602  ASSERT_FALSE(a.IsEmpty());
1603  // b is allowed to be empty
1604 
1605  // unflipped a vs flipped (empty) b yields a
1606  EXPECT_FALSE(a.Intersection(flip_lr(b)).has_value()) << label;
1607  EXPECT_FALSE(a.Intersection(flip_tb(b)).has_value()) << label;
1608  EXPECT_FALSE(a.Intersection(flip_lrtb(b)).has_value()) << label;
1609 
1610  // flipped (empty) a vs unflipped b yields b
1611  EXPECT_FALSE(flip_lr(a).Intersection(b).has_value()) << label;
1612  EXPECT_FALSE(flip_tb(a).Intersection(b).has_value()) << label;
1613  EXPECT_FALSE(flip_lrtb(a).Intersection(b).has_value()) << label;
1614 
1615  // flipped (empty) a vs flipped (empty) b yields empty
1616  EXPECT_FALSE(flip_lr(a).Intersection(flip_lr(b)).has_value()) << label;
1617  EXPECT_FALSE(flip_tb(a).Intersection(flip_tb(b)).has_value()) << label;
1618  EXPECT_FALSE(flip_lrtb(a).Intersection(flip_lrtb(b)).has_value()) << label;
1619  };
1620 
1621  auto test_non_empty = [&check_nans, &check_empty_flips](
1622  const Rect& a, const Rect& b, const Rect& result) {
1623  ASSERT_FALSE(a.IsEmpty()) << a;
1624  // b is allowed to be empty
1625 
1626  std::stringstream stream;
1627  stream << a << " union " << b;
1628  auto label = stream.str();
1629 
1630  EXPECT_TRUE(a.Intersection(b).has_value()) << label;
1631  EXPECT_TRUE(b.Intersection(a).has_value()) << label;
1632  EXPECT_EQ(a.Intersection(b), result) << label;
1633  EXPECT_EQ(b.Intersection(a), result) << label;
1634  check_empty_flips(a, b, label);
1635  check_nans(a, b, label);
1636  };
1637 
1638  auto test_empty = [&check_nans, &check_empty_flips](const Rect& a,
1639  const Rect& b) {
1640  ASSERT_FALSE(a.IsEmpty()) << a;
1641  // b is allowed to be empty
1642 
1643  std::stringstream stream;
1644  stream << a << " union " << b;
1645  auto label = stream.str();
1646 
1647  EXPECT_FALSE(a.Intersection(b).has_value()) << label;
1648  EXPECT_FALSE(b.Intersection(a).has_value()) << label;
1649  check_empty_flips(a, b, label);
1650  check_nans(a, b, label);
1651  };
1652 
1653  {
1654  auto a = Rect::MakeXYWH(100, 100, 100, 100);
1655  auto b = Rect::MakeXYWH(0, 0, 0, 0);
1656 
1657  test_empty(a, b);
1658  }
1659 
1660  {
1661  auto a = Rect::MakeXYWH(100, 100, 100, 100);
1662  auto b = Rect::MakeXYWH(10, 10, 0, 0);
1663 
1664  test_empty(a, b);
1665  }
1666 
1667  {
1668  auto a = Rect::MakeXYWH(0, 0, 100, 100);
1669  auto b = Rect::MakeXYWH(10, 10, 100, 100);
1670  auto expected = Rect::MakeXYWH(10, 10, 90, 90);
1671 
1672  test_non_empty(a, b, expected);
1673  }
1674 
1675  {
1676  auto a = Rect::MakeXYWH(0, 0, 100, 100);
1677  auto b = Rect::MakeXYWH(100, 100, 100, 100);
1678 
1679  test_empty(a, b);
1680  }
1681 
1682  {
1683  auto a = Rect::MakeMaximum();
1684  auto b = Rect::MakeXYWH(10, 10, 300, 300);
1685 
1686  test_non_empty(a, b, b);
1687  }
1688 
1689  {
1690  auto a = Rect::MakeMaximum();
1691  auto b = Rect::MakeMaximum();
1692 
1693  test_non_empty(a, b, Rect::MakeMaximum());
1694  }
1695 }

References impeller::saturated::b, flip_lr(), flip_lrtb(), flip_tb(), impeller::TRect< T >::Intersection(), impeller::TRect< T >::IsEmpty(), impeller::TRect< T >::IsFinite(), impeller::TRect< Scalar >::MakeMaximum(), impeller::TRect< Scalar >::MakeXYWH(), and swap_nan().

◆ TEST() [280/360]

impeller::testing::TEST ( RectTest  ,
RectIntersectsWithRect   
)

Definition at line 1902 of file rect_unittests.cc.

1902  {
1903  auto check_nans = [](const Rect& a, const Rect& b, const std::string& label) {
1904  ASSERT_TRUE(a.IsFinite()) << label;
1905  ASSERT_TRUE(b.IsFinite()) << label;
1906 
1907  for (int i = 1; i < 16; i++) {
1908  // NaN in a produces b
1909  EXPECT_FALSE(swap_nan(a, i).IntersectsWithRect(b))
1910  << label << ", index = " << i;
1911  // NaN in b produces a
1912  EXPECT_FALSE(a.IntersectsWithRect(swap_nan(b, i)))
1913  << label << ", index = " << i;
1914  // NaN in both is empty
1915  for (int j = 1; j < 16; j++) {
1916  EXPECT_FALSE(swap_nan(a, i).IntersectsWithRect(swap_nan(b, j)))
1917  << label << ", indices = " << i << ", " << j;
1918  }
1919  }
1920  };
1921 
1922  auto check_empty_flips = [](const Rect& a, const Rect& b,
1923  const std::string& label) {
1924  ASSERT_FALSE(a.IsEmpty());
1925  // b is allowed to be empty
1926 
1927  // unflipped a vs flipped (empty) b yields a
1928  EXPECT_FALSE(a.IntersectsWithRect(flip_lr(b))) << label;
1929  EXPECT_FALSE(a.IntersectsWithRect(flip_tb(b))) << label;
1930  EXPECT_FALSE(a.IntersectsWithRect(flip_lrtb(b))) << label;
1931 
1932  // flipped (empty) a vs unflipped b yields b
1933  EXPECT_FALSE(flip_lr(a).IntersectsWithRect(b)) << label;
1934  EXPECT_FALSE(flip_tb(a).IntersectsWithRect(b)) << label;
1935  EXPECT_FALSE(flip_lrtb(a).IntersectsWithRect(b)) << label;
1936 
1937  // flipped (empty) a vs flipped (empty) b yields empty
1938  EXPECT_FALSE(flip_lr(a).IntersectsWithRect(flip_lr(b))) << label;
1939  EXPECT_FALSE(flip_tb(a).IntersectsWithRect(flip_tb(b))) << label;
1940  EXPECT_FALSE(flip_lrtb(a).IntersectsWithRect(flip_lrtb(b))) << label;
1941  };
1942 
1943  auto test_non_empty = [&check_nans, &check_empty_flips](const Rect& a,
1944  const Rect& b) {
1945  ASSERT_FALSE(a.IsEmpty()) << a;
1946  // b is allowed to be empty
1947 
1948  std::stringstream stream;
1949  stream << a << " union " << b;
1950  auto label = stream.str();
1951 
1952  EXPECT_TRUE(a.IntersectsWithRect(b)) << label;
1953  EXPECT_TRUE(b.IntersectsWithRect(a)) << label;
1954  check_empty_flips(a, b, label);
1955  check_nans(a, b, label);
1956  };
1957 
1958  auto test_empty = [&check_nans, &check_empty_flips](const Rect& a,
1959  const Rect& b) {
1960  ASSERT_FALSE(a.IsEmpty()) << a;
1961  // b is allowed to be empty
1962 
1963  std::stringstream stream;
1964  stream << a << " union " << b;
1965  auto label = stream.str();
1966 
1967  EXPECT_FALSE(a.IntersectsWithRect(b)) << label;
1968  EXPECT_FALSE(b.IntersectsWithRect(a)) << label;
1969  check_empty_flips(a, b, label);
1970  check_nans(a, b, label);
1971  };
1972 
1973  {
1974  auto a = Rect::MakeXYWH(100, 100, 100, 100);
1975  auto b = Rect::MakeXYWH(0, 0, 0, 0);
1976 
1977  test_empty(a, b);
1978  }
1979 
1980  {
1981  auto a = Rect::MakeXYWH(100, 100, 100, 100);
1982  auto b = Rect::MakeXYWH(10, 10, 0, 0);
1983 
1984  test_empty(a, b);
1985  }
1986 
1987  {
1988  auto a = Rect::MakeXYWH(0, 0, 100, 100);
1989  auto b = Rect::MakeXYWH(10, 10, 100, 100);
1990 
1991  test_non_empty(a, b);
1992  }
1993 
1994  {
1995  auto a = Rect::MakeXYWH(0, 0, 100, 100);
1996  auto b = Rect::MakeXYWH(100, 100, 100, 100);
1997 
1998  test_empty(a, b);
1999  }
2000 
2001  {
2002  auto a = Rect::MakeMaximum();
2003  auto b = Rect::MakeXYWH(10, 10, 100, 100);
2004 
2005  test_non_empty(a, b);
2006  }
2007 
2008  {
2009  auto a = Rect::MakeMaximum();
2010  auto b = Rect::MakeMaximum();
2011 
2012  test_non_empty(a, b);
2013  }
2014 }

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

impeller::testing::TEST ( RectTest  ,
RectMakeMaximum   
)

Definition at line 575 of file rect_unittests.cc.

575  {
576  Rect rect = Rect::MakeMaximum();
577  auto inf = std::numeric_limits<Scalar>::infinity();
578  auto min = std::numeric_limits<Scalar>::lowest();
579  auto max = std::numeric_limits<Scalar>::max();
580 
581  EXPECT_EQ(rect.GetLeft(), min);
582  EXPECT_EQ(rect.GetTop(), min);
583  EXPECT_EQ(rect.GetRight(), max);
584  EXPECT_EQ(rect.GetBottom(), max);
585  EXPECT_EQ(rect.GetX(), min);
586  EXPECT_EQ(rect.GetY(), min);
587  EXPECT_EQ(rect.GetWidth(), inf);
588  EXPECT_EQ(rect.GetHeight(), inf);
589  EXPECT_FALSE(rect.IsEmpty());
590  EXPECT_TRUE(rect.IsFinite());
591 }

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

impeller::testing::TEST ( RectTest  ,
RectMakePointBounds   
)

Definition at line 2950 of file rect_unittests.cc.

2950  {
2951  {
2952  std::vector<Point> points{{1, 5}, {4, -1}, {0, 6}};
2953  auto r = Rect::MakePointBounds(points.begin(), points.end());
2954  auto expected = Rect::MakeXYWH(0, -1, 4, 7);
2955  EXPECT_TRUE(r.has_value());
2956  if (r.has_value()) {
2957  EXPECT_RECT_NEAR(r.value(), expected);
2958  }
2959  }
2960  {
2961  std::vector<Point> points;
2962  std::optional<Rect> r = Rect::MakePointBounds(points.begin(), points.end());
2963  EXPECT_FALSE(r.has_value());
2964  }
2965 }

References EXPECT_RECT_NEAR, impeller::TRect< Scalar >::MakePointBounds(), and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST() [283/360]

impeller::testing::TEST ( RectTest  ,
RectMakeSize   
)

Definition at line 545 of file rect_unittests.cc.

545  {
546  {
547  Size s(100, 200);
548  Rect r = Rect::MakeSize(s);
549  Rect expected = Rect::MakeLTRB(0, 0, 100, 200);
550  EXPECT_RECT_NEAR(r, expected);
551  }
552 
553  {
554  ISize s(100, 200);
555  Rect r = Rect::MakeSize(s);
556  Rect expected = Rect::MakeLTRB(0, 0, 100, 200);
557  EXPECT_RECT_NEAR(r, expected);
558  }
559 
560  {
561  Size s(100, 200);
562  IRect r = IRect::MakeSize(s);
563  IRect expected = IRect::MakeLTRB(0, 0, 100, 200);
564  EXPECT_EQ(r, expected);
565  }
566 
567  {
568  ISize s(100, 200);
569  IRect r = IRect::MakeSize(s);
570  IRect expected = IRect::MakeLTRB(0, 0, 100, 200);
571  EXPECT_EQ(r, expected);
572  }
573 }

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

◆ TEST() [284/360]

impeller::testing::TEST ( RectTest  ,
RectOriginSizeXYWHGetters   
)

Definition at line 657 of file rect_unittests.cc.

657  {
658  {
659  Rect r = Rect::MakeOriginSize({10, 20}, {50, 40});
660  EXPECT_EQ(r.GetOrigin(), Point(10, 20));
661  EXPECT_EQ(r.GetSize(), Size(50, 40));
662  EXPECT_EQ(r.GetX(), 10);
663  EXPECT_EQ(r.GetY(), 20);
664  EXPECT_EQ(r.GetWidth(), 50);
665  EXPECT_EQ(r.GetHeight(), 40);
666  auto expected_array = std::array<Scalar, 4>{10, 20, 50, 40};
667  EXPECT_EQ(r.GetXYWH(), expected_array);
668  }
669 
670  {
671  Rect r = Rect::MakeLTRB(10, 20, 50, 40);
672  EXPECT_EQ(r.GetOrigin(), Point(10, 20));
673  EXPECT_EQ(r.GetSize(), Size(40, 20));
674  EXPECT_EQ(r.GetX(), 10);
675  EXPECT_EQ(r.GetY(), 20);
676  EXPECT_EQ(r.GetWidth(), 40);
677  EXPECT_EQ(r.GetHeight(), 20);
678  auto expected_array = std::array<Scalar, 4>{10, 20, 40, 20};
679  EXPECT_EQ(r.GetXYWH(), expected_array);
680  }
681 }

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

impeller::testing::TEST ( RectTest  ,
RectOverflowLTRB   
)

Definition at line 339 of file rect_unittests.cc.

339  {
340  auto min = std::numeric_limits<Scalar>::lowest();
341  auto max = std::numeric_limits<Scalar>::max();
342  auto inf = std::numeric_limits<Scalar>::infinity();
343 
344  // 8 cases:
345  // finite negative X, max W
346  // ~min X, ~max W
347  // finite negative Y, max H
348  // ~min Y, ~max H
349  // finite positive X, min W
350  // ~min X, ~min W
351  // finite positive Y, min H
352  // ~min Y, ~min H
353 
354  // a small finite value subtracted from a max value will remain max
355  // a very large finite value (like min) subtracted from max will go to inf
356 
357  {
358  Rect rect = Rect::MakeLTRB(-5.0f, 10.0f, max, 25.0f);
359 
360  EXPECT_EQ(rect.GetLeft(), -5.0f);
361  EXPECT_EQ(rect.GetTop(), 10.0f);
362  EXPECT_EQ(rect.GetRight(), max);
363  EXPECT_EQ(rect.GetBottom(), 25.0f);
364  EXPECT_EQ(rect.GetX(), -5.0f);
365  EXPECT_EQ(rect.GetY(), 10.0f);
366  EXPECT_EQ(rect.GetWidth(), max);
367  EXPECT_EQ(rect.GetHeight(), 15.0f);
368  EXPECT_FALSE(rect.IsEmpty());
369  EXPECT_TRUE(rect.IsFinite());
370  }
371 
372  {
373  Rect rect = Rect::MakeLTRB(min + 5.0f, 10.0f, max - 5.0f, 25.0f);
374 
375  EXPECT_EQ(rect.GetLeft(), min + 5.0f);
376  EXPECT_EQ(rect.GetTop(), 10.0f);
377  EXPECT_EQ(rect.GetRight(), max - 5.0f);
378  EXPECT_EQ(rect.GetBottom(), 25.0f);
379  EXPECT_EQ(rect.GetX(), min + 5.0f);
380  EXPECT_EQ(rect.GetY(), 10.0f);
381  EXPECT_EQ(rect.GetWidth(), inf);
382  EXPECT_EQ(rect.GetHeight(), 15.0f);
383  EXPECT_FALSE(rect.IsEmpty());
384  EXPECT_TRUE(rect.IsFinite());
385  }
386 
387  {
388  Rect rect = Rect::MakeLTRB(5.0f, -10.0f, 20.0f, max);
389 
390  EXPECT_EQ(rect.GetLeft(), 5.0f);
391  EXPECT_EQ(rect.GetTop(), -10.0f);
392  EXPECT_EQ(rect.GetRight(), 20.0f);
393  EXPECT_EQ(rect.GetBottom(), max);
394  EXPECT_EQ(rect.GetX(), 5.0f);
395  EXPECT_EQ(rect.GetY(), -10.0f);
396  EXPECT_EQ(rect.GetWidth(), 15.0f);
397  EXPECT_EQ(rect.GetHeight(), max);
398  EXPECT_FALSE(rect.IsEmpty());
399  EXPECT_TRUE(rect.IsFinite());
400  }
401 
402  {
403  Rect rect = Rect::MakeLTRB(5.0f, min + 10.0f, 20.0f, max - 15.0f);
404 
405  EXPECT_EQ(rect.GetLeft(), 5.0f);
406  EXPECT_EQ(rect.GetTop(), min + 10.0f);
407  EXPECT_EQ(rect.GetRight(), 20.0f);
408  EXPECT_EQ(rect.GetBottom(), max - 15.0f);
409  EXPECT_EQ(rect.GetX(), 5.0f);
410  EXPECT_EQ(rect.GetY(), min + 10.0f);
411  EXPECT_EQ(rect.GetWidth(), 15.0f);
412  EXPECT_EQ(rect.GetHeight(), inf);
413  EXPECT_FALSE(rect.IsEmpty());
414  EXPECT_TRUE(rect.IsFinite());
415  }
416 
417  {
418  Rect rect = Rect::MakeLTRB(5.0f, 10.0f, min, 25.0f);
419 
420  EXPECT_EQ(rect.GetLeft(), 5.0f);
421  EXPECT_EQ(rect.GetTop(), 10.0f);
422  EXPECT_EQ(rect.GetRight(), min);
423  EXPECT_EQ(rect.GetBottom(), 25.0f);
424  EXPECT_EQ(rect.GetX(), 5.0f);
425  EXPECT_EQ(rect.GetY(), 10.0f);
426  EXPECT_EQ(rect.GetWidth(), min);
427  EXPECT_EQ(rect.GetHeight(), 15.0f);
428  EXPECT_TRUE(rect.IsEmpty());
429  EXPECT_TRUE(rect.IsFinite());
430  }
431 
432  {
433  Rect rect = Rect::MakeLTRB(max - 5.0f, 10.0f, min + 10.0f, 25.0f);
434 
435  EXPECT_EQ(rect.GetLeft(), max - 5.0f);
436  EXPECT_EQ(rect.GetTop(), 10.0f);
437  EXPECT_EQ(rect.GetRight(), min + 10.0f);
438  EXPECT_EQ(rect.GetBottom(), 25.0f);
439  EXPECT_EQ(rect.GetX(), max - 5.0f);
440  EXPECT_EQ(rect.GetY(), 10.0f);
441  EXPECT_EQ(rect.GetWidth(), -inf);
442  EXPECT_EQ(rect.GetHeight(), 15.0f);
443  EXPECT_TRUE(rect.IsEmpty());
444  EXPECT_TRUE(rect.IsFinite());
445  }
446 
447  {
448  Rect rect = Rect::MakeLTRB(5.0f, 10.0f, 20.0f, min);
449 
450  EXPECT_EQ(rect.GetLeft(), 5.0f);
451  EXPECT_EQ(rect.GetTop(), 10.0f);
452  EXPECT_EQ(rect.GetRight(), 20.0f);
453  EXPECT_EQ(rect.GetBottom(), min);
454  EXPECT_EQ(rect.GetX(), 5.0f);
455  EXPECT_EQ(rect.GetY(), 10.0f);
456  EXPECT_EQ(rect.GetWidth(), 15.0f);
457  EXPECT_EQ(rect.GetHeight(), min);
458  EXPECT_TRUE(rect.IsEmpty());
459  EXPECT_TRUE(rect.IsFinite());
460  }
461 
462  {
463  Rect rect = Rect::MakeLTRB(5.0f, max - 5.0f, 20.0f, min + 10.0f);
464 
465  EXPECT_EQ(rect.GetLeft(), 5.0f);
466  EXPECT_EQ(rect.GetTop(), max - 5.0f);
467  EXPECT_EQ(rect.GetRight(), 20.0f);
468  EXPECT_EQ(rect.GetBottom(), min + 10.0f);
469  EXPECT_EQ(rect.GetX(), 5.0f);
470  EXPECT_EQ(rect.GetY(), max - 5.0f);
471  EXPECT_EQ(rect.GetWidth(), 15.0f);
472  EXPECT_EQ(rect.GetHeight(), -inf);
473  EXPECT_TRUE(rect.IsEmpty());
474  EXPECT_TRUE(rect.IsFinite());
475  }
476 }

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

impeller::testing::TEST ( RectTest  ,
RectOverflowXYWH   
)

Definition at line 133 of file rect_unittests.cc.

133  {
134  auto min = std::numeric_limits<Scalar>::lowest();
135  auto max = std::numeric_limits<Scalar>::max();
136  auto inf = std::numeric_limits<Scalar>::infinity();
137 
138  // 8 cases:
139  // finite X, max W
140  // max X, max W
141  // finite Y, max H
142  // max Y, max H
143  // finite X, min W
144  // min X, min W
145  // finite Y, min H
146  // min Y, min H
147 
148  // a small finite value added to a max value will remain max
149  // a very large finite value (like max) added to max will go to infinity
150 
151  {
152  Rect rect = Rect::MakeXYWH(5.0, 10.0f, max, 15.0f);
153 
154  EXPECT_EQ(rect.GetLeft(), 5.0f);
155  EXPECT_EQ(rect.GetTop(), 10.0f);
156  EXPECT_EQ(rect.GetRight(), max);
157  EXPECT_EQ(rect.GetBottom(), 25.0f);
158  EXPECT_EQ(rect.GetX(), 5.0f);
159  EXPECT_EQ(rect.GetY(), 10.0f);
160  EXPECT_EQ(rect.GetWidth(), max);
161  EXPECT_EQ(rect.GetHeight(), 15.0f);
162  EXPECT_FALSE(rect.IsEmpty());
163  EXPECT_TRUE(rect.IsFinite());
164  }
165 
166  {
167  Rect rect = Rect::MakeXYWH(max, 10.0f, max, 15.0f);
168 
169  EXPECT_EQ(rect.GetLeft(), max);
170  EXPECT_EQ(rect.GetTop(), 10.0f);
171  EXPECT_EQ(rect.GetRight(), inf);
172  EXPECT_EQ(rect.GetBottom(), 25.0f);
173  EXPECT_EQ(rect.GetX(), max);
174  EXPECT_EQ(rect.GetY(), 10.0f);
175  EXPECT_EQ(rect.GetWidth(), inf);
176  EXPECT_EQ(rect.GetHeight(), 15.0f);
177  EXPECT_FALSE(rect.IsEmpty());
178  EXPECT_FALSE(rect.IsFinite());
179  }
180 
181  {
182  Rect rect = Rect::MakeXYWH(5.0f, 10.0f, 20.0f, max);
183 
184  EXPECT_EQ(rect.GetLeft(), 5.0f);
185  EXPECT_EQ(rect.GetTop(), 10.0f);
186  EXPECT_EQ(rect.GetRight(), 25.0f);
187  EXPECT_EQ(rect.GetBottom(), max);
188  EXPECT_EQ(rect.GetX(), 5.0f);
189  EXPECT_EQ(rect.GetY(), 10.0f);
190  EXPECT_EQ(rect.GetWidth(), 20.0f);
191  EXPECT_EQ(rect.GetHeight(), max);
192  EXPECT_FALSE(rect.IsEmpty());
193  EXPECT_TRUE(rect.IsFinite());
194  }
195 
196  {
197  Rect rect = Rect::MakeXYWH(5.0f, max, 20.0f, max);
198 
199  EXPECT_EQ(rect.GetLeft(), 5.0f);
200  EXPECT_EQ(rect.GetTop(), max);
201  EXPECT_EQ(rect.GetRight(), 25.0f);
202  EXPECT_EQ(rect.GetBottom(), inf);
203  EXPECT_EQ(rect.GetX(), 5.0f);
204  EXPECT_EQ(rect.GetY(), max);
205  EXPECT_EQ(rect.GetWidth(), 20.0f);
206  EXPECT_EQ(rect.GetHeight(), inf);
207  EXPECT_FALSE(rect.IsEmpty());
208  EXPECT_FALSE(rect.IsFinite());
209  }
210 
211  {
212  Rect rect = Rect::MakeXYWH(5.0, 10.0f, min, 15.0f);
213 
214  EXPECT_EQ(rect.GetLeft(), 5.0f);
215  EXPECT_EQ(rect.GetTop(), 10.0f);
216  EXPECT_EQ(rect.GetRight(), min);
217  EXPECT_EQ(rect.GetBottom(), 25.0f);
218  EXPECT_EQ(rect.GetX(), 5.0f);
219  EXPECT_EQ(rect.GetY(), 10.0f);
220  EXPECT_EQ(rect.GetWidth(), min);
221  EXPECT_EQ(rect.GetHeight(), 15.0f);
222  EXPECT_TRUE(rect.IsEmpty());
223  EXPECT_TRUE(rect.IsFinite());
224  }
225 
226  {
227  Rect rect = Rect::MakeXYWH(min, 10.0f, min, 15.0f);
228 
229  EXPECT_EQ(rect.GetLeft(), min);
230  EXPECT_EQ(rect.GetTop(), 10.0f);
231  EXPECT_EQ(rect.GetRight(), -inf);
232  EXPECT_EQ(rect.GetBottom(), 25.0f);
233  EXPECT_EQ(rect.GetX(), min);
234  EXPECT_EQ(rect.GetY(), 10.0f);
235  EXPECT_EQ(rect.GetWidth(), -inf);
236  EXPECT_EQ(rect.GetHeight(), 15.0f);
237  EXPECT_TRUE(rect.IsEmpty());
238  EXPECT_FALSE(rect.IsFinite());
239  }
240 
241  {
242  Rect rect = Rect::MakeXYWH(5.0f, 10.0f, 20.0f, min);
243 
244  EXPECT_EQ(rect.GetLeft(), 5.0f);
245  EXPECT_EQ(rect.GetTop(), 10.0f);
246  EXPECT_EQ(rect.GetRight(), 25.0f);
247  EXPECT_EQ(rect.GetBottom(), min);
248  EXPECT_EQ(rect.GetX(), 5.0f);
249  EXPECT_EQ(rect.GetY(), 10.0f);
250  EXPECT_EQ(rect.GetWidth(), 20.0f);
251  EXPECT_EQ(rect.GetHeight(), min);
252  EXPECT_TRUE(rect.IsEmpty());
253  EXPECT_TRUE(rect.IsFinite());
254  }
255 
256  {
257  Rect rect = Rect::MakeXYWH(5.0f, min, 20.0f, min);
258 
259  EXPECT_EQ(rect.GetLeft(), 5.0f);
260  EXPECT_EQ(rect.GetTop(), min);
261  EXPECT_EQ(rect.GetRight(), 25.0f);
262  EXPECT_EQ(rect.GetBottom(), -inf);
263  EXPECT_EQ(rect.GetX(), 5.0f);
264  EXPECT_EQ(rect.GetY(), min);
265  EXPECT_EQ(rect.GetWidth(), 20.0f);
266  EXPECT_EQ(rect.GetHeight(), -inf);
267  EXPECT_TRUE(rect.IsEmpty());
268  EXPECT_FALSE(rect.IsFinite());
269  }
270 }

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

impeller::testing::TEST ( RectTest  ,
RectProject   
)

Definition at line 2995 of file rect_unittests.cc.

2995  {
2996  {
2997  auto r = Rect::MakeLTRB(-100, -100, 100, 100);
2998  auto actual = r.Project(r);
2999  auto expected = Rect::MakeLTRB(0, 0, 1, 1);
3000  EXPECT_RECT_NEAR(expected, actual);
3001  }
3002  {
3003  auto r = Rect::MakeLTRB(-100, -100, 100, 100);
3004  auto actual = r.Project(Rect::MakeLTRB(0, 0, 100, 100));
3005  auto expected = Rect::MakeLTRB(0.5, 0.5, 1, 1);
3006  EXPECT_RECT_NEAR(expected, actual);
3007  }
3008 }

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

◆ TEST() [288/360]

impeller::testing::TEST ( RectTest  ,
RectRound   
)

Definition at line 3034 of file rect_unittests.cc.

3034  {
3035  {
3036  auto r = Rect::MakeLTRB(-100, -200, 300, 400);
3037  EXPECT_EQ(Rect::Round(r), r);
3038  }
3039  {
3040  auto r = Rect::MakeLTRB(-100.4, -200.4, 300.4, 400.4);
3041  EXPECT_EQ(Rect::Round(r), Rect::MakeLTRB(-100, -200, 300, 400));
3042  }
3043  {
3044  auto r = Rect::MakeLTRB(-100.5, -200.5, 300.5, 400.5);
3045  EXPECT_EQ(Rect::Round(r), Rect::MakeLTRB(-101, -201, 301, 401));
3046  }
3047 }

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

◆ TEST() [289/360]

impeller::testing::TEST ( RectTest  ,
RectRoundOut   
)

Definition at line 3010 of file rect_unittests.cc.

3010  {
3011  {
3012  auto r = Rect::MakeLTRB(-100, -200, 300, 400);
3013  EXPECT_EQ(Rect::RoundOut(r), r);
3014  }
3015  {
3016  auto r = Rect::MakeLTRB(-100.1, -200.1, 300.1, 400.1);
3017  EXPECT_EQ(Rect::RoundOut(r), Rect::MakeLTRB(-101, -201, 301, 401));
3018  }
3019 }

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

◆ TEST() [290/360]

impeller::testing::TEST ( RectTest  ,
RectRoundOutEmpty   
)

Definition at line 709 of file rect_unittests.cc.

709  {
710  Rect rect;
711 
712  EXPECT_EQ(Rect::RoundOut(rect), Rect());
713 
714  EXPECT_EQ(IRect::RoundOut(rect), IRect());
715 }

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

◆ TEST() [291/360]

impeller::testing::TEST ( RectTest  ,
RectRoundOutSimple   
)

Definition at line 717 of file rect_unittests.cc.

717  {
718  Rect rect = Rect::MakeLTRB(5.125f, 10.75f, 20.625f, 25.375f);
719 
720  EXPECT_EQ(Rect::RoundOut(rect), Rect::MakeLTRB(5.0f, 10.0f, 21.0f, 26.0f));
721 
722  EXPECT_EQ(IRect::RoundOut(rect), IRect::MakeLTRB(5, 10, 21, 26));
723 }

References impeller::TRect< Scalar >::MakeLTRB(), impeller::TRect< T >::MakeLTRB(), impeller::TRect< T >::RoundOut(), and impeller::TRect< Scalar >::RoundOut().

◆ TEST() [292/360]

impeller::testing::TEST ( RectTest  ,
RectRoundOutToIRectHuge   
)

Definition at line 725 of file rect_unittests.cc.

725  {
726  auto test = [](int corners) {
727  EXPECT_TRUE(corners >= 0 && corners <= 0xf);
728  Scalar l, t, r, b;
729  int64_t il, it, ir, ib;
730  l = il = 50;
731  t = it = 50;
732  r = ir = 80;
733  b = ib = 80;
734  if ((corners & (1 << 0)) != 0) {
735  l = -1E20;
736  il = std::numeric_limits<int64_t>::min();
737  }
738  if ((corners & (1 << 1)) != 0) {
739  t = -1E20;
740  it = std::numeric_limits<int64_t>::min();
741  }
742  if ((corners & (1 << 2)) != 0) {
743  r = +1E20;
744  ir = std::numeric_limits<int64_t>::max();
745  }
746  if ((corners & (1 << 3)) != 0) {
747  b = +1E20;
748  ib = std::numeric_limits<int64_t>::max();
749  }
750 
751  Rect rect = Rect::MakeLTRB(l, t, r, b);
752  IRect irect = IRect::RoundOut(rect);
753  EXPECT_EQ(irect.GetLeft(), il) << corners;
754  EXPECT_EQ(irect.GetTop(), it) << corners;
755  EXPECT_EQ(irect.GetRight(), ir) << corners;
756  EXPECT_EQ(irect.GetBottom(), ib) << corners;
757  };
758 
759  for (int corners = 0; corners <= 15; corners++) {
760  test(corners);
761  }
762 }

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

impeller::testing::TEST ( RectTest  ,
RectScale   
)

Definition at line 884 of file rect_unittests.cc.

884  {
885  auto test1 = [](Rect rect, Scalar scale) {
886  Rect expected = Rect::MakeXYWH(rect.GetX() * scale, //
887  rect.GetY() * scale, //
888  rect.GetWidth() * scale, //
889  rect.GetHeight() * scale);
890 
891  EXPECT_RECT_NEAR(rect.Scale(scale), expected) //
892  << rect << " * " << scale;
893  EXPECT_RECT_NEAR(rect.Scale(scale, scale), expected) //
894  << rect << " * " << scale;
895  EXPECT_RECT_NEAR(rect.Scale(Point(scale, scale)), expected) //
896  << rect << " * " << scale;
897  EXPECT_RECT_NEAR(rect.Scale(Size(scale, scale)), expected) //
898  << rect << " * " << scale;
899  };
900 
901  auto test2 = [&test1](Rect rect, Scalar scale_x, Scalar scale_y) {
902  Rect expected = Rect::MakeXYWH(rect.GetX() * scale_x, //
903  rect.GetY() * scale_y, //
904  rect.GetWidth() * scale_x, //
905  rect.GetHeight() * scale_y);
906 
907  EXPECT_RECT_NEAR(rect.Scale(scale_x, scale_y), expected) //
908  << rect << " * " << scale_x << ", " << scale_y;
909  EXPECT_RECT_NEAR(rect.Scale(Point(scale_x, scale_y)), expected) //
910  << rect << " * " << scale_x << ", " << scale_y;
911  EXPECT_RECT_NEAR(rect.Scale(Size(scale_x, scale_y)), expected) //
912  << rect << " * " << scale_x << ", " << scale_y;
913 
914  test1(rect, scale_x);
915  test1(rect, scale_y);
916  };
917 
918  test2(Rect::MakeLTRB(10, 15, 100, 150), 1.0, 0.0);
919  test2(Rect::MakeLTRB(10, 15, 100, 150), 0.0, 1.0);
920  test2(Rect::MakeLTRB(10, 15, 100, 150), 0.0, 0.0);
921  test2(Rect::MakeLTRB(10, 15, 100, 150), 2.5, 3.5);
922  test2(Rect::MakeLTRB(10, 15, 100, 150), 3.5, 2.5);
923  test2(Rect::MakeLTRB(10, 15, -100, 150), 2.5, 3.5);
924  test2(Rect::MakeLTRB(10, 15, 100, -150), 2.5, 3.5);
925  test2(Rect::MakeLTRB(10, 15, 100, 150), -2.5, 3.5);
926  test2(Rect::MakeLTRB(10, 15, 100, 150), 2.5, -3.5);
927 }

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(), impeller::TRect< T >::Scale(), and scale.

◆ TEST() [294/360]

impeller::testing::TEST ( RectTest  ,
RectShift   
)

Definition at line 2934 of file rect_unittests.cc.

2934  {
2935  auto r = Rect::MakeLTRB(0, 0, 100, 100);
2936 
2937  EXPECT_EQ(r.Shift(Point(10, 5)), Rect::MakeLTRB(10, 5, 110, 105));
2938  EXPECT_EQ(r.Shift(Point(-10, -5)), Rect::MakeLTRB(-10, -5, 90, 95));
2939 }

References impeller::TRect< Scalar >::MakeLTRB().

◆ TEST() [295/360]

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

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

impeller::testing::TEST ( RectTest  ,
RectUnion   
)

Definition at line 1313 of file rect_unittests.cc.

1313  {
1314  auto check_nans = [](const Rect& a, const Rect& b, const std::string& label) {
1315  ASSERT_TRUE(a.IsFinite()) << label;
1316  ASSERT_TRUE(b.IsFinite()) << label;
1317  ASSERT_FALSE(a.Union(b).IsEmpty());
1318 
1319  for (int i = 1; i < 16; i++) {
1320  // NaN in a produces b
1321  EXPECT_EQ(swap_nan(a, i).Union(b), b) << label << ", index = " << i;
1322  // NaN in b produces a
1323  EXPECT_EQ(a.Union(swap_nan(b, i)), a) << label << ", index = " << i;
1324  // NaN in both is empty
1325  for (int j = 1; j < 16; j++) {
1326  EXPECT_TRUE(swap_nan(a, i).Union(swap_nan(b, j)).IsEmpty())
1327  << label << ", indices = " << i << ", " << j;
1328  }
1329  }
1330  };
1331 
1332  auto check_empty_flips = [](const Rect& a, const Rect& b,
1333  const std::string& label) {
1334  ASSERT_FALSE(a.IsEmpty());
1335  // b is allowed to be empty
1336 
1337  // unflipped a vs flipped (empty) b yields a
1338  EXPECT_EQ(a.Union(flip_lr(b)), a) << label;
1339  EXPECT_EQ(a.Union(flip_tb(b)), a) << label;
1340  EXPECT_EQ(a.Union(flip_lrtb(b)), a) << label;
1341 
1342  // flipped (empty) a vs unflipped b yields b
1343  EXPECT_EQ(flip_lr(a).Union(b), b) << label;
1344  EXPECT_EQ(flip_tb(a).Union(b), b) << label;
1345  EXPECT_EQ(flip_lrtb(a).Union(b), b) << label;
1346 
1347  // flipped (empty) a vs flipped (empty) b yields empty
1348  EXPECT_TRUE(flip_lr(a).Union(flip_lr(b)).IsEmpty()) << label;
1349  EXPECT_TRUE(flip_tb(a).Union(flip_tb(b)).IsEmpty()) << label;
1350  EXPECT_TRUE(flip_lrtb(a).Union(flip_lrtb(b)).IsEmpty()) << label;
1351  };
1352 
1353  auto test = [&check_nans, &check_empty_flips](const Rect& a, const Rect& b,
1354  const Rect& result) {
1355  ASSERT_FALSE(a.IsEmpty()) << a;
1356  // b is allowed to be empty
1357 
1358  std::stringstream stream;
1359  stream << a << " union " << b;
1360  auto label = stream.str();
1361 
1362  EXPECT_EQ(a.Union(b), result) << label;
1363  EXPECT_EQ(b.Union(a), result) << label;
1364  check_empty_flips(a, b, label);
1365  check_nans(a, b, label);
1366  };
1367 
1368  {
1369  auto a = Rect::MakeXYWH(100, 100, 100, 100);
1370  auto b = Rect::MakeXYWH(0, 0, 0, 0);
1371  auto expected = Rect::MakeXYWH(100, 100, 100, 100);
1372  test(a, b, expected);
1373  }
1374 
1375  {
1376  auto a = Rect::MakeXYWH(100, 100, 100, 100);
1377  auto b = Rect::MakeXYWH(0, 0, 1, 1);
1378  auto expected = Rect::MakeXYWH(0, 0, 200, 200);
1379  test(a, b, expected);
1380  }
1381 
1382  {
1383  auto a = Rect::MakeXYWH(100, 100, 100, 100);
1384  auto b = Rect::MakeXYWH(10, 10, 1, 1);
1385  auto expected = Rect::MakeXYWH(10, 10, 190, 190);
1386  test(a, b, expected);
1387  }
1388 
1389  {
1390  auto a = Rect::MakeXYWH(0, 0, 100, 100);
1391  auto b = Rect::MakeXYWH(10, 10, 100, 100);
1392  auto expected = Rect::MakeXYWH(0, 0, 110, 110);
1393  test(a, b, expected);
1394  }
1395 
1396  {
1397  auto a = Rect::MakeXYWH(0, 0, 100, 100);
1398  auto b = Rect::MakeXYWH(100, 100, 100, 100);
1399  auto expected = Rect::MakeXYWH(0, 0, 200, 200);
1400  test(a, b, expected);
1401  }
1402 }

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

impeller::testing::TEST ( RectTest  ,
RectXYWHIsEmpty   
)

Definition at line 1127 of file rect_unittests.cc.

1127  {
1128  auto nan = std::numeric_limits<Scalar>::quiet_NaN();
1129 
1130  // Non-empty
1131  EXPECT_FALSE(Rect::MakeXYWH(1.5, 2.3, 10.5, 7.2).IsEmpty());
1132 
1133  // Empty both width and height both 0 or negative, in all combinations
1134  EXPECT_TRUE(Rect::MakeXYWH(1.5, 2.3, 0.0, 0.0).IsEmpty());
1135  EXPECT_TRUE(Rect::MakeXYWH(1.5, 2.3, -1.0, -1.0).IsEmpty());
1136  EXPECT_TRUE(Rect::MakeXYWH(1.5, 2.3, 0.0, -1.0).IsEmpty());
1137  EXPECT_TRUE(Rect::MakeXYWH(1.5, 2.3, -1.0, 0.0).IsEmpty());
1138 
1139  // Empty for 0 or negative width or height (but not both at the same time)
1140  EXPECT_TRUE(Rect::MakeXYWH(1.5, 2.3, 10.5, 0.0).IsEmpty());
1141  EXPECT_TRUE(Rect::MakeXYWH(1.5, 2.3, 10.5, -1.0).IsEmpty());
1142  EXPECT_TRUE(Rect::MakeXYWH(1.5, 2.3, 0.0, 7.2).IsEmpty());
1143  EXPECT_TRUE(Rect::MakeXYWH(1.5, 2.3, -1.0, 7.2).IsEmpty());
1144 
1145  // Empty for NaN in width or height or both
1146  EXPECT_TRUE(Rect::MakeXYWH(1.5, 2.3, 10.5, nan).IsEmpty());
1147  EXPECT_TRUE(Rect::MakeXYWH(1.5, 2.3, nan, 7.2).IsEmpty());
1148  EXPECT_TRUE(Rect::MakeXYWH(1.5, 2.3, nan, nan).IsEmpty());
1149 }

References impeller::TRect< Scalar >::MakeXYWH().

◆ TEST() [299/360]

impeller::testing::TEST ( RectTest  ,
TransformAndClipBounds   
)

Definition at line 3067 of file rect_unittests.cc.

3067  {
3068  {
3069  // This matrix should clip no corners.
3070  auto matrix = impeller::Matrix::MakeColumn(
3071  // clang-format off
3072  2.0f, 0.0f, 0.0f, 0.0f,
3073  0.0f, 4.0f, 0.0f, 0.0f,
3074  0.0f, 0.0f, 1.0f, 0.0f,
3075  0.0f, 0.0f, 0.0f, 8.0f
3076  // clang-format on
3077  );
3078  Rect src = Rect::MakeLTRB(100.0f, 100.0f, 200.0f, 200.0f);
3079  // None of these should have a W<0
3080  EXPECT_EQ(matrix.TransformHomogenous(src.GetLeftTop()),
3081  Vector3(200.0f, 400.0f, 8.0f));
3082  EXPECT_EQ(matrix.TransformHomogenous(src.GetRightTop()),
3083  Vector3(400.0f, 400.0f, 8.0f));
3084  EXPECT_EQ(matrix.TransformHomogenous(src.GetLeftBottom()),
3085  Vector3(200.0f, 800.0f, 8.0f));
3086  EXPECT_EQ(matrix.TransformHomogenous(src.GetRightBottom()),
3087  Vector3(400.0f, 800.0f, 8.0f));
3088 
3089  Rect expect = Rect::MakeLTRB(25.0f, 50.0f, 50.0f, 100.0f);
3090  EXPECT_FALSE(src.TransformAndClipBounds(matrix).IsEmpty());
3091  EXPECT_EQ(src.TransformAndClipBounds(matrix), expect);
3092  }
3093 
3094  {
3095  // This matrix should clip one corner.
3096  auto matrix = impeller::Matrix::MakeColumn(
3097  // clang-format off
3098  2.0f, 0.0f, 0.0f, -0.01f,
3099  0.0f, 2.0f, 0.0f, -0.006f,
3100  0.0f, 0.0f, 1.0f, 0.0f,
3101  0.0f, 0.0f, 0.0f, 3.0f
3102  // clang-format on
3103  );
3104  Rect src = Rect::MakeLTRB(100.0f, 100.0f, 200.0f, 200.0f);
3105  // Exactly one of these should have a W<0
3106  EXPECT_VECTOR3_NEAR(matrix.TransformHomogenous(src.GetLeftTop()),
3107  Vector3(200.0f, 200.0f, 1.4f));
3108  EXPECT_VECTOR3_NEAR(matrix.TransformHomogenous(src.GetRightTop()),
3109  Vector3(400.0f, 200.0f, 0.4f));
3110  EXPECT_VECTOR3_NEAR(matrix.TransformHomogenous(src.GetLeftBottom()),
3111  Vector3(200.0f, 400.0f, 0.8f));
3112  EXPECT_VECTOR3_NEAR(matrix.TransformHomogenous(src.GetRightBottom()),
3113  Vector3(400.0f, 400.0f, -0.2f));
3114 
3115  Rect expect = Rect::MakeLTRB(142.85715f, 142.85715f, 6553600.f, 6553600.f);
3116  EXPECT_FALSE(src.TransformAndClipBounds(matrix).IsEmpty());
3117  EXPECT_RECT_NEAR(src.TransformAndClipBounds(matrix), expect);
3118  }
3119 
3120  {
3121  // This matrix should clip two corners.
3122  auto matrix = impeller::Matrix::MakeColumn(
3123  // clang-format off
3124  2.0f, 0.0f, 0.0f, -.015f,
3125  0.0f, 2.0f, 0.0f, -.006f,
3126  0.0f, 0.0f, 1.0f, 0.0f,
3127  0.0f, 0.0f, 0.0f, 3.0f
3128  // clang-format on
3129  );
3130  Rect src = Rect::MakeLTRB(100.0f, 100.0f, 200.0f, 200.0f);
3131  // Exactly two of these should have a W<0
3132  EXPECT_VECTOR3_NEAR(matrix.TransformHomogenous(src.GetLeftTop()),
3133  Vector3(200.0f, 200.0f, 0.9f));
3134  EXPECT_VECTOR3_NEAR(matrix.TransformHomogenous(src.GetRightTop()),
3135  Vector3(400.0f, 200.0f, -0.6f));
3136  EXPECT_VECTOR3_NEAR(matrix.TransformHomogenous(src.GetLeftBottom()),
3137  Vector3(200.0f, 400.0f, 0.3f));
3138  EXPECT_VECTOR3_NEAR(matrix.TransformHomogenous(src.GetRightBottom()),
3139  Vector3(400.0f, 400.0f, -1.2f));
3140 
3141  Rect expect = Rect::MakeLTRB(222.2222f, 222.2222f, 5898373.f, 6553600.f);
3142  EXPECT_FALSE(src.TransformAndClipBounds(matrix).IsEmpty());
3143  EXPECT_RECT_NEAR(src.TransformAndClipBounds(matrix), expect);
3144  }
3145 
3146  {
3147  // This matrix should clip three corners.
3148  auto matrix = impeller::Matrix::MakeColumn(
3149  // clang-format off
3150  2.0f, 0.0f, 0.0f, -.02f,
3151  0.0f, 2.0f, 0.0f, -.006f,
3152  0.0f, 0.0f, 1.0f, 0.0f,
3153  0.0f, 0.0f, 0.0f, 3.0f
3154  // clang-format on
3155  );
3156  Rect src = Rect::MakeLTRB(100.0f, 100.0f, 200.0f, 200.0f);
3157  // Exactly three of these should have a W<0
3158  EXPECT_VECTOR3_NEAR(matrix.TransformHomogenous(src.GetLeftTop()),
3159  Vector3(200.0f, 200.0f, 0.4f));
3160  EXPECT_VECTOR3_NEAR(matrix.TransformHomogenous(src.GetRightTop()),
3161  Vector3(400.0f, 200.0f, -1.6f));
3162  EXPECT_VECTOR3_NEAR(matrix.TransformHomogenous(src.GetLeftBottom()),
3163  Vector3(200.0f, 400.0f, -0.2f));
3164  EXPECT_VECTOR3_NEAR(matrix.TransformHomogenous(src.GetRightBottom()),
3165  Vector3(400.0f, 400.0f, -2.2f));
3166 
3167  Rect expect = Rect::MakeLTRB(499.99988f, 499.99988f, 5898340.f, 4369400.f);
3168  EXPECT_FALSE(src.TransformAndClipBounds(matrix).IsEmpty());
3169  EXPECT_RECT_NEAR(src.TransformAndClipBounds(matrix), expect);
3170  }
3171 
3172  {
3173  // This matrix should clip all four corners.
3174  auto matrix = impeller::Matrix::MakeColumn(
3175  // clang-format off
3176  2.0f, 0.0f, 0.0f, -.025f,
3177  0.0f, 2.0f, 0.0f, -.006f,
3178  0.0f, 0.0f, 1.0f, 0.0f,
3179  0.0f, 0.0f, 0.0f, 3.0f
3180  // clang-format on
3181  );
3182  Rect src = Rect::MakeLTRB(100.0f, 100.0f, 200.0f, 200.0f);
3183  // All of these should have a W<0
3184  EXPECT_VECTOR3_NEAR(matrix.TransformHomogenous(src.GetLeftTop()),
3185  Vector3(200.0f, 200.0f, -0.1f));
3186  EXPECT_VECTOR3_NEAR(matrix.TransformHomogenous(src.GetRightTop()),
3187  Vector3(400.0f, 200.0f, -2.6f));
3188  EXPECT_VECTOR3_NEAR(matrix.TransformHomogenous(src.GetLeftBottom()),
3189  Vector3(200.0f, 400.0f, -0.7f));
3190  EXPECT_VECTOR3_NEAR(matrix.TransformHomogenous(src.GetRightBottom()),
3191  Vector3(400.0f, 400.0f, -3.2f));
3192 
3193  EXPECT_TRUE(src.TransformAndClipBounds(matrix).IsEmpty());
3194  }
3195 }

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

impeller::testing::TEST ( RenderPassBuilder  ,
CreatesMSAAResolveWithCorrectStore   
)

Definition at line 102 of file render_pass_builder_vk_unittests.cc.

102  {
103  RenderPassBuilderVK builder = RenderPassBuilderVK();
104  auto const context = MockVulkanContextBuilder().Build();
105 
106  // Create an MSAA color attachment.
107  builder.SetColorAttachment(0, PixelFormat::kR8G8B8A8UNormInt,
108  SampleCount::kCount4, LoadAction::kClear,
109  StoreAction::kMultisampleResolve);
110 
111  auto render_pass = builder.Build(context->GetDevice());
112 
113  EXPECT_TRUE(!!render_pass);
114 
115  auto maybe_color = builder.GetColorAttachments().find(0u);
116  ASSERT_NE(maybe_color, builder.GetColorAttachments().end());
117  auto color = maybe_color->second;
118 
119  // MSAA Texture.
120  EXPECT_EQ(color.initialLayout, vk::ImageLayout::eGeneral);
121  EXPECT_EQ(color.finalLayout, vk::ImageLayout::eGeneral);
122  EXPECT_EQ(color.loadOp, vk::AttachmentLoadOp::eClear);
123  EXPECT_EQ(color.storeOp, vk::AttachmentStoreOp::eDontCare);
124 
125  auto maybe_resolve = builder.GetResolves().find(0u);
126  ASSERT_NE(maybe_resolve, builder.GetResolves().end());
127  auto resolve = maybe_resolve->second;
128 
129  // MSAA Resolve Texture.
130  EXPECT_EQ(resolve.initialLayout, vk::ImageLayout::eGeneral);
131  EXPECT_EQ(resolve.finalLayout, vk::ImageLayout::eGeneral);
132  EXPECT_EQ(resolve.loadOp, vk::AttachmentLoadOp::eClear);
133  EXPECT_EQ(resolve.storeOp, vk::AttachmentStoreOp::eStore);
134 }

References impeller::RenderPassBuilderVK::Build(), color, impeller::RenderPassBuilderVK::GetColorAttachments(), impeller::RenderPassBuilderVK::GetResolves(), impeller::kClear, impeller::kCount4, impeller::kMultisampleResolve, impeller::kR8G8B8A8UNormInt, and impeller::RenderPassBuilderVK::SetColorAttachment().

◆ TEST() [301/360]

impeller::testing::TEST ( RenderPassBuilder  ,
CreatesRenderPassWithCombinedDepthStencil   
)

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  // Create a single color attachment with a transient depth stencil.
35  builder.SetColorAttachment(0, PixelFormat::kR8G8B8A8UNormInt,
36  SampleCount::kCount1, LoadAction::kClear,
37  StoreAction::kStore);
38  builder.SetDepthStencilAttachment(PixelFormat::kD24UnormS8Uint,
39  SampleCount::kCount1, LoadAction::kDontCare,
40  StoreAction::kDontCare);
41 
42  auto render_pass = builder.Build(context->GetDevice());
43 
44  EXPECT_TRUE(!!render_pass);
45 
46  auto maybe_color = builder.GetColorAttachments().find(0u);
47  ASSERT_NE(maybe_color, builder.GetColorAttachments().end());
48  auto color = maybe_color->second;
49 
50  EXPECT_EQ(color.initialLayout, vk::ImageLayout::eGeneral);
51  EXPECT_EQ(color.finalLayout, vk::ImageLayout::eGeneral);
52  EXPECT_EQ(color.loadOp, vk::AttachmentLoadOp::eClear);
53  EXPECT_EQ(color.storeOp, vk::AttachmentStoreOp::eStore);
54 
55  auto maybe_depth_stencil = builder.GetDepthStencil();
56  ASSERT_TRUE(maybe_depth_stencil.has_value());
57  if (!maybe_depth_stencil.has_value()) {
58  return;
59  }
60  auto depth_stencil = maybe_depth_stencil.value();
61 
62  EXPECT_EQ(depth_stencil.initialLayout, vk::ImageLayout::eUndefined);
63  EXPECT_EQ(depth_stencil.finalLayout,
64  vk::ImageLayout::eDepthStencilAttachmentOptimal);
65  EXPECT_EQ(depth_stencil.loadOp, vk::AttachmentLoadOp::eDontCare);
66  EXPECT_EQ(depth_stencil.storeOp, vk::AttachmentStoreOp::eDontCare);
67  EXPECT_EQ(depth_stencil.stencilLoadOp, vk::AttachmentLoadOp::eDontCare);
68  EXPECT_EQ(depth_stencil.stencilStoreOp, vk::AttachmentStoreOp::eDontCare);
69 }

References impeller::RenderPassBuilderVK::Build(), color, impeller::RenderPassBuilderVK::GetColorAttachments(), impeller::RenderPassBuilderVK::GetDepthStencil(), impeller::kClear, impeller::kCount1, impeller::kD24UnormS8Uint, impeller::kDontCare, impeller::kR8G8B8A8UNormInt, impeller::kStore, impeller::RenderPassBuilderVK::SetColorAttachment(), and impeller::RenderPassBuilderVK::SetDepthStencilAttachment().

◆ TEST() [302/360]

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

impeller::testing::TEST ( RenderPassBuilder  ,
CreatesRenderPassWithOnlyStencil   
)

Definition at line 71 of file render_pass_builder_vk_unittests.cc.

71  {
72  RenderPassBuilderVK builder = RenderPassBuilderVK();
73  auto const context = MockVulkanContextBuilder().Build();
74 
75  // Create a single color attachment with a transient depth stencil.
76  builder.SetColorAttachment(0, PixelFormat::kR8G8B8A8UNormInt,
77  SampleCount::kCount1, LoadAction::kClear,
78  StoreAction::kStore);
79  builder.SetStencilAttachment(PixelFormat::kS8UInt, SampleCount::kCount1,
80  LoadAction::kDontCare, StoreAction::kDontCare);
81 
82  auto render_pass = builder.Build(context->GetDevice());
83 
84  EXPECT_TRUE(!!render_pass);
85 
86  auto maybe_depth_stencil = builder.GetDepthStencil();
87  ASSERT_TRUE(maybe_depth_stencil.has_value());
88  if (!maybe_depth_stencil.has_value()) {
89  return;
90  }
91  auto depth_stencil = maybe_depth_stencil.value();
92 
93  EXPECT_EQ(depth_stencil.initialLayout, vk::ImageLayout::eUndefined);
94  EXPECT_EQ(depth_stencil.finalLayout,
95  vk::ImageLayout::eDepthStencilAttachmentOptimal);
96  EXPECT_EQ(depth_stencil.loadOp, vk::AttachmentLoadOp::eDontCare);
97  EXPECT_EQ(depth_stencil.storeOp, vk::AttachmentStoreOp::eDontCare);
98  EXPECT_EQ(depth_stencil.stencilLoadOp, vk::AttachmentLoadOp::eDontCare);
99  EXPECT_EQ(depth_stencil.stencilStoreOp, vk::AttachmentStoreOp::eDontCare);
100 }

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

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 }

References impeller::saturated::b, and impeller::ResourceManagerVK::Create().

◆ TEST() [305/360]

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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 }

References impeller::ShaderArchiveWriter::AddShader(), impeller::ShaderArchiveWriter::CreateMapping(), CreateMappingFromString(), CreateStringFromMapping(), impeller::ShaderArchive::GetMapping(), impeller::ShaderArchive::GetShaderCount(), impeller::ShaderArchive::IsValid(), impeller::kFragment, and impeller::kVertex.

◆ TEST() [327/360]

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

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

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

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

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

impeller::testing::TEST ( SkiaConversionsTest  ,
GradientConversionNonMonotonic   
)

Definition at line 151 of file skia_conversions_unittests.cc.

151  {
152  std::vector<flutter::DlColor> colors = {
153  flutter::DlColor::kBlue(), flutter::DlColor::kGreen(),
154  flutter::DlColor::kGreen(), flutter::DlColor::kRed()};
155  std::vector<float> stops = {0.0, 0.5, 0.4, 1.0};
156  const auto gradient =
157  flutter::DlColorSource::MakeLinear(SkPoint::Make(0, 0), //
158  SkPoint::Make(1.0, 1.0), //
159  4, //
160  colors.data(), //
161  stops.data(), //
162  flutter::DlTileMode::kClamp, //
163  nullptr //
164  );
165 
166  std::vector<Color> converted_colors;
167  std::vector<Scalar> converted_stops;
168  skia_conversions::ConvertStops(gradient.get(), converted_colors,
169  converted_stops);
170 
171  // Value is clamped to 0.5
172  ASSERT_TRUE(ScalarNearlyEqual(converted_stops[0], 0.0f));
173  ASSERT_TRUE(ScalarNearlyEqual(converted_stops[1], 0.5f));
174  ASSERT_TRUE(ScalarNearlyEqual(converted_stops[2], 0.5f));
175  ASSERT_TRUE(ScalarNearlyEqual(converted_stops[3], 1.0f));
176 }

References impeller::skia_conversions::ConvertStops(), and impeller::ScalarNearlyEqual().

◆ TEST() [333/360]

impeller::testing::TEST ( SkiaConversionsTest  ,
GradientMissing0   
)

Definition at line 73 of file skia_conversions_unittests.cc.

73  {
74  std::vector<flutter::DlColor> colors = {flutter::DlColor::kBlue(),
75  flutter::DlColor::kRed()};
76  std::vector<float> stops = {0.5, 1.0};
77  const auto gradient =
78  flutter::DlColorSource::MakeLinear(SkPoint::Make(0, 0), //
79  SkPoint::Make(1.0, 1.0), //
80  2, //
81  colors.data(), //
82  stops.data(), //
83  flutter::DlTileMode::kClamp, //
84  nullptr //
85  );
86 
87  std::vector<Color> converted_colors;
88  std::vector<Scalar> converted_stops;
89  skia_conversions::ConvertStops(gradient.get(), converted_colors,
90  converted_stops);
91 
92  // First color is inserted as blue.
93  ASSERT_TRUE(ScalarNearlyEqual(converted_colors[0].blue, 1.0f));
94  ASSERT_TRUE(ScalarNearlyEqual(converted_stops[0], 0.0f));
95  ASSERT_TRUE(ScalarNearlyEqual(converted_stops[1], 0.5f));
96  ASSERT_TRUE(ScalarNearlyEqual(converted_stops[2], 1.0f));
97 }

References impeller::skia_conversions::ConvertStops(), and impeller::ScalarNearlyEqual().

◆ TEST() [334/360]

impeller::testing::TEST ( SkiaConversionsTest  ,
GradientMissingLastValue   
)

Definition at line 99 of file skia_conversions_unittests.cc.

99  {
100  std::vector<flutter::DlColor> colors = {flutter::DlColor::kBlue(),
101  flutter::DlColor::kRed()};
102  std::vector<float> stops = {0.0, .5};
103  const auto gradient =
104  flutter::DlColorSource::MakeLinear(SkPoint::Make(0, 0), //
105  SkPoint::Make(1.0, 1.0), //
106  2, //
107  colors.data(), //
108  stops.data(), //
109  flutter::DlTileMode::kClamp, //
110  nullptr //
111  );
112 
113  std::vector<Color> converted_colors;
114  std::vector<Scalar> converted_stops;
115  skia_conversions::ConvertStops(gradient.get(), converted_colors,
116  converted_stops);
117 
118  // Last color is inserted as red.
119  ASSERT_TRUE(ScalarNearlyEqual(converted_colors[2].red, 1.0f));
120  ASSERT_TRUE(ScalarNearlyEqual(converted_stops[0], 0.0f));
121  ASSERT_TRUE(ScalarNearlyEqual(converted_stops[1], 0.5f));
122  ASSERT_TRUE(ScalarNearlyEqual(converted_stops[2], 1.0f));
123 }

References impeller::skia_conversions::ConvertStops(), and impeller::ScalarNearlyEqual().

◆ TEST() [335/360]

impeller::testing::TEST ( SkiaConversionsTest  ,
GradientStopConversion   
)

Definition at line 47 of file skia_conversions_unittests.cc.

47  {
48  // Typical gradient.
49  std::vector<flutter::DlColor> colors = {flutter::DlColor::kBlue(),
50  flutter::DlColor::kRed(),
51  flutter::DlColor::kGreen()};
52  std::vector<float> stops = {0.0, 0.5, 1.0};
53  const auto gradient =
54  flutter::DlColorSource::MakeLinear(SkPoint::Make(0, 0), //
55  SkPoint::Make(1.0, 1.0), //
56  3, //
57  colors.data(), //
58  stops.data(), //
59  flutter::DlTileMode::kClamp, //
60  nullptr //
61  );
62 
63  std::vector<Color> converted_colors;
64  std::vector<Scalar> converted_stops;
65  skia_conversions::ConvertStops(gradient.get(), converted_colors,
66  converted_stops);
67 
68  ASSERT_TRUE(ScalarNearlyEqual(converted_stops[0], 0.0f));
69  ASSERT_TRUE(ScalarNearlyEqual(converted_stops[1], 0.5f));
70  ASSERT_TRUE(ScalarNearlyEqual(converted_stops[2], 1.0f));
71 }

References impeller::skia_conversions::ConvertStops(), and impeller::ScalarNearlyEqual().

◆ TEST() [336/360]

impeller::testing::TEST ( SkiaConversionsTest  ,
GradientStopGreaterThan1   
)

Definition at line 125 of file skia_conversions_unittests.cc.

125  {
126  std::vector<flutter::DlColor> colors = {flutter::DlColor::kBlue(),
127  flutter::DlColor::kGreen(),
128  flutter::DlColor::kRed()};
129  std::vector<float> stops = {0.0, 100, 1.0};
130  const auto gradient =
131  flutter::DlColorSource::MakeLinear(SkPoint::Make(0, 0), //
132  SkPoint::Make(1.0, 1.0), //
133  3, //
134  colors.data(), //
135  stops.data(), //
136  flutter::DlTileMode::kClamp, //
137  nullptr //
138  );
139 
140  std::vector<Color> converted_colors;
141  std::vector<Scalar> converted_stops;
142  skia_conversions::ConvertStops(gradient.get(), converted_colors,
143  converted_stops);
144 
145  // Value is clamped to 1.0
146  ASSERT_TRUE(ScalarNearlyEqual(converted_stops[0], 0.0f));
147  ASSERT_TRUE(ScalarNearlyEqual(converted_stops[1], 1.0f));
148  ASSERT_TRUE(ScalarNearlyEqual(converted_stops[2], 1.0f));
149 }

References impeller::skia_conversions::ConvertStops(), and impeller::ScalarNearlyEqual().

◆ TEST() [337/360]

impeller::testing::TEST ( SkiaConversionsTest  ,
IsNearlySimpleRRect   
)

Definition at line 178 of file skia_conversions_unittests.cc.

178  {
180  SkRRect::MakeRectXY(SkRect::MakeLTRB(0, 0, 10, 10), 10, 10)));
182  SkRRect::MakeRectXY(SkRect::MakeLTRB(0, 0, 10, 10), 10, 9.999)));
184  SkRRect::MakeRectXY(SkRect::MakeLTRB(0, 0, 10, 10), 10, 9)));
185 }

References impeller::skia_conversions::IsNearlySimpleRRect().

◆ TEST() [338/360]

impeller::testing::TEST ( SkiaConversionsTest  ,
SkPointToPoint   
)

Definition at line 15 of file skia_conversions_unittests.cc.

15  {
16  for (int x = -100; x < 100; x += 4) {
17  for (int y = -100; y < 100; y += 4) {
18  EXPECT_EQ(skia_conversions::ToPoint(SkPoint::Make(x * 0.25f, y * 0.25f)),
19  Point(x * 0.25f, y * 0.25f));
20  }
21  }
22 }

References impeller::skia_conversions::ToPoint().

◆ TEST() [339/360]

impeller::testing::TEST ( SkiaConversionsTest  ,
SkPointToSize   
)

Definition at line 24 of file skia_conversions_unittests.cc.

24  {
25  for (int x = -100; x < 100; x += 4) {
26  for (int y = -100; y < 100; y += 4) {
27  EXPECT_EQ(skia_conversions::ToSize(SkPoint::Make(x * 0.25f, y * 0.25f)),
28  Size(x * 0.25f, y * 0.25f));
29  }
30  }
31 }

References impeller::skia_conversions::ToSize().

◆ TEST() [340/360]

impeller::testing::TEST ( SkiaConversionsTest  ,
ToColor   
)

Definition at line 33 of file skia_conversions_unittests.cc.

33  {
34  // Create a color with alpha, red, green, and blue values that are all
35  // trivially divisible by 255 so that we can test the conversion results in
36  // correct scalar values.
37  // AARRGGBB
38  const flutter::DlColor color = flutter::DlColor(0x8040C020);
39  auto converted_color = skia_conversions::ToColor(color);
40 
41  ASSERT_TRUE(ScalarNearlyEqual(converted_color.alpha, 0x80 * (1.0f / 255)));
42  ASSERT_TRUE(ScalarNearlyEqual(converted_color.red, 0x40 * (1.0f / 255)));
43  ASSERT_TRUE(ScalarNearlyEqual(converted_color.green, 0xC0 * (1.0f / 255)));
44  ASSERT_TRUE(ScalarNearlyEqual(converted_color.blue, 0x20 * (1.0f / 255)));
45 }

References color, impeller::ScalarNearlyEqual(), and impeller::skia_conversions::ToColor().

◆ TEST() [341/360]

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

Definition at line 86 of file base_unittests.cc.

86  {
87  ASSERT_EQ(SPrintF("%sx%d", "Hello", 12), "Hellox12");
88  ASSERT_EQ(SPrintF(""), "");
89  ASSERT_EQ(SPrintF("Hello"), "Hello");
90  ASSERT_EQ(SPrintF("%sx%.2f", "Hello", 12.122222), "Hellox12.12");
91 }

References impeller::SPrintF().

◆ TEST() [342/360]

impeller::testing::TEST ( TessellatorTest  ,
ChecksConcurrentPolylineUsage   
)

Definition at line 515 of file tessellator_unittests.cc.

515  {
516  auto tessellator = std::make_shared<Tessellator>();
517  PathBuilder builder;
518  builder.AddLine({0, 0}, {100, 100});
519  auto path = builder.TakePath();
520 
521  auto polyline = tessellator->CreateTempPolyline(path, 0.1);
522  EXPECT_DEBUG_DEATH(tessellator->CreateTempPolyline(path, 0.1),
523  "point_buffer_");
524 }

References impeller::PathBuilder::AddLine(), polyline, and impeller::PathBuilder::TakePath().

◆ TEST() [343/360]

impeller::testing::TEST ( TessellatorTest  ,
CircleVertexCounts   
)

Definition at line 139 of file tessellator_unittests.cc.

139  {
140  auto tessellator = std::make_shared<Tessellator>();
141 
142  auto test = [&tessellator](const Matrix& transform, Scalar radius) {
143  auto generator = tessellator->FilledCircle(transform, {}, radius);
144  size_t quadrant_divisions = generator.GetVertexCount() / 4;
145 
146  // Confirm the approximation error is within the currently accepted
147  // |kCircleTolerance| value advertised by |CircleTessellator|.
148  // (With an additional 1% tolerance for floating point rounding.)
149  double angle = kPiOver2 / quadrant_divisions;
150  Point first = {radius, 0};
151  Point next = {static_cast<Scalar>(cos(angle) * radius),
152  static_cast<Scalar>(sin(angle) * radius)};
153  Point midpoint = (first + next) * 0.5;
154  EXPECT_GE(midpoint.GetLength(),
155  radius - Tessellator::kCircleTolerance * 1.01)
156  << ", transform = " << transform << ", radius = " << radius
157  << ", divisions = " << quadrant_divisions;
158  };
159 
160  test({}, 0.0);
161  test({}, 0.9);
162  test({}, 1.0);
163  test({}, 1.9);
164  test(Matrix::MakeScale(Vector2(2.0, 2.0)), 0.95);
165  test({}, 2.0);
166  test(Matrix::MakeScale(Vector2(2.0, 2.0)), 1.0);
167  test({}, 11.9);
168  test({}, 12.0);
169  test({}, 35.9);
170  for (int i = 36; i < 10000; i += 4) {
171  test({}, i);
172  }
173 }

References impeller::TPoint< T >::GetLength(), impeller::Tessellator::kCircleTolerance, impeller::kPiOver2, impeller::Matrix::MakeScale(), and transform.

◆ TEST() [344/360]

impeller::testing::TEST ( TessellatorTest  ,
EarlyReturnEmptyConvexShape   
)

Definition at line 499 of file tessellator_unittests.cc.

499  {
500  // This path is not technically empty (it has a size in one dimension),
501  // but is otherwise completely flat.
502  PathBuilder builder;
503  builder.MoveTo({0, 0});
504  builder.MoveTo({10, 10}, /*relative=*/true);
505 
506  std::vector<Point> points;
507  std::vector<uint16_t> indices;
508  Tessellator::TessellateConvexInternal(builder.TakePath(), points, indices,
509  3.0);
510 
511  EXPECT_TRUE(points.empty());
512 }

References impeller::PathBuilder::MoveTo(), impeller::PathBuilder::TakePath(), and impeller::Tessellator::TessellateConvexInternal().

◆ TEST() [345/360]

impeller::testing::TEST ( TessellatorTest  ,
FilledCircleTessellationVertices   
)

Definition at line 175 of file tessellator_unittests.cc.

175  {
176  auto tessellator = std::make_shared<Tessellator>();
177 
178  auto test = [&tessellator](const Matrix& transform, const Point& center,
179  Scalar radius) {
180  auto generator = tessellator->FilledCircle(transform, center, radius);
181  EXPECT_EQ(generator.GetTriangleType(), PrimitiveType::kTriangleStrip);
182 
183  auto vertex_count = generator.GetVertexCount();
184  auto vertices = std::vector<Point>();
185  generator.GenerateVertices([&vertices](const Point& p) { //
186  vertices.push_back(p);
187  });
188  EXPECT_EQ(vertices.size(), vertex_count);
189  ASSERT_EQ(vertex_count % 4, 0u);
190 
191  auto quadrant_count = vertex_count / 4;
192  for (size_t i = 0; i < quadrant_count; i++) {
193  double angle = kPiOver2 * i / (quadrant_count - 1);
194  double degrees = angle * 180.0 / kPi;
195  double rsin = sin(angle) * radius;
196  // Note that cos(radians(90 degrees)) isn't exactly 0.0 like it should be
197  double rcos = (i == quadrant_count - 1) ? 0.0f : cos(angle) * radius;
198  EXPECT_POINT_NEAR(vertices[i * 2],
199  Point(center.x - rcos, center.y + rsin))
200  << "vertex " << i << ", angle = " << degrees << std::endl;
201  EXPECT_POINT_NEAR(vertices[i * 2 + 1],
202  Point(center.x - rcos, center.y - rsin))
203  << "vertex " << i << ", angle = " << degrees << std::endl;
204  EXPECT_POINT_NEAR(vertices[vertex_count - i * 2 - 1],
205  Point(center.x + rcos, center.y - rsin))
206  << "vertex " << i << ", angle = " << degrees << std::endl;
207  EXPECT_POINT_NEAR(vertices[vertex_count - i * 2 - 2],
208  Point(center.x + rcos, center.y + rsin))
209  << "vertex " << i << ", angle = " << degrees << std::endl;
210  }
211  };
212 
213  test({}, {}, 2.0);
214  test({}, {10, 10}, 2.0);
215  test(Matrix::MakeScale({500.0, 500.0, 0.0}), {}, 2.0);
216  test(Matrix::MakeScale({0.002, 0.002, 0.0}), {}, 1000.0);
217 }

References EXPECT_POINT_NEAR, impeller::kPi, impeller::kPiOver2, impeller::kTriangleStrip, impeller::Matrix::MakeScale(), and transform.

◆ TEST() [346/360]

impeller::testing::TEST ( TessellatorTest  ,
FilledEllipseTessellationVertices   
)

Definition at line 364 of file tessellator_unittests.cc.

364  {
365  auto tessellator = std::make_shared<Tessellator>();
366 
367  auto test = [&tessellator](const Matrix& transform, const Rect& bounds) {
368  auto center = bounds.GetCenter();
369  auto half_size = bounds.GetSize() * 0.5f;
370 
371  auto generator = tessellator->FilledEllipse(transform, bounds);
372  EXPECT_EQ(generator.GetTriangleType(), PrimitiveType::kTriangleStrip);
373 
374  auto vertex_count = generator.GetVertexCount();
375  auto vertices = std::vector<Point>();
376  generator.GenerateVertices([&vertices](const Point& p) { //
377  vertices.push_back(p);
378  });
379  EXPECT_EQ(vertices.size(), vertex_count);
380  ASSERT_EQ(vertex_count % 4, 0u);
381 
382  auto quadrant_count = vertex_count / 4;
383  for (size_t i = 0; i < quadrant_count; i++) {
384  double angle = kPiOver2 * i / (quadrant_count - 1);
385  double degrees = angle * 180.0 / kPi;
386  // Note that cos(radians(90 degrees)) isn't exactly 0.0 like it should be
387  double rcos =
388  (i == quadrant_count - 1) ? 0.0f : cos(angle) * half_size.width;
389  double rsin = sin(angle) * half_size.height;
390  EXPECT_POINT_NEAR(vertices[i * 2],
391  Point(center.x - rcos, center.y + rsin))
392  << "vertex " << i << ", angle = " << degrees << ", " //
393  << "bounds = " << bounds << std::endl;
394  EXPECT_POINT_NEAR(vertices[i * 2 + 1],
395  Point(center.x - rcos, center.y - rsin))
396  << "vertex " << i << ", angle = " << degrees << ", " //
397  << "bounds = " << bounds << std::endl;
398  EXPECT_POINT_NEAR(vertices[vertex_count - i * 2 - 1],
399  Point(center.x + rcos, center.y - rsin))
400  << "vertex " << i << ", angle = " << degrees << ", " //
401  << "bounds = " << bounds << std::endl;
402  EXPECT_POINT_NEAR(vertices[vertex_count - i * 2 - 2],
403  Point(center.x + rcos, center.y + rsin))
404  << "vertex " << i << ", angle = " << degrees << ", " //
405  << "bounds = " << bounds << std::endl;
406  }
407  };
408 
409  // Square bounds should actually use the circle generator, but its
410  // results should match the same math as the ellipse generator.
411  test({}, Rect::MakeXYWH(0, 0, 2, 2));
412 
413  test({}, Rect::MakeXYWH(0, 0, 2, 3));
414  test({}, Rect::MakeXYWH(0, 0, 3, 2));
415  test({}, Rect::MakeXYWH(5, 10, 2, 3));
416  test({}, Rect::MakeXYWH(16, 7, 3, 2));
417  test(Matrix::MakeScale({500.0, 500.0, 0.0}), Rect::MakeXYWH(5, 10, 3, 2));
418  test(Matrix::MakeScale({500.0, 500.0, 0.0}), Rect::MakeXYWH(5, 10, 2, 3));
419  test(Matrix::MakeScale({0.002, 0.002, 0.0}),
420  Rect::MakeXYWH(5000, 10000, 3000, 2000));
421  test(Matrix::MakeScale({0.002, 0.002, 0.0}),
422  Rect::MakeXYWH(5000, 10000, 2000, 3000));
423 }

References EXPECT_POINT_NEAR, impeller::kPi, impeller::kPiOver2, impeller::kTriangleStrip, impeller::Matrix::MakeScale(), impeller::TRect< Scalar >::MakeXYWH(), and transform.

◆ TEST() [347/360]

impeller::testing::TEST ( TessellatorTest  ,
FilledRoundRectTessellationVertices   
)

Definition at line 425 of file tessellator_unittests.cc.

425  {
426  auto tessellator = std::make_shared<Tessellator>();
427 
428  auto test = [&tessellator](const Matrix& transform, const Rect& bounds,
429  const Size& radii) {
430  FML_DCHECK(radii.width * 2 <= bounds.GetWidth()) << radii << bounds;
431  FML_DCHECK(radii.height * 2 <= bounds.GetHeight()) << radii << bounds;
432 
433  Scalar middle_left = bounds.GetX() + radii.width;
434  Scalar middle_top = bounds.GetY() + radii.height;
435  Scalar middle_right = bounds.GetX() + bounds.GetWidth() - radii.width;
436  Scalar middle_bottom = bounds.GetY() + bounds.GetHeight() - radii.height;
437 
438  auto generator = tessellator->FilledRoundRect(transform, bounds, radii);
439  EXPECT_EQ(generator.GetTriangleType(), PrimitiveType::kTriangleStrip);
440 
441  auto vertex_count = generator.GetVertexCount();
442  auto vertices = std::vector<Point>();
443  generator.GenerateVertices([&vertices](const Point& p) { //
444  vertices.push_back(p);
445  });
446  EXPECT_EQ(vertices.size(), vertex_count);
447  ASSERT_EQ(vertex_count % 4, 0u);
448 
449  auto quadrant_count = vertex_count / 4;
450  for (size_t i = 0; i < quadrant_count; i++) {
451  double angle = kPiOver2 * i / (quadrant_count - 1);
452  double degrees = angle * 180.0 / kPi;
453  // Note that cos(radians(90 degrees)) isn't exactly 0.0 like it should be
454  double rcos = (i == quadrant_count - 1) ? 0.0f : cos(angle) * radii.width;
455  double rsin = sin(angle) * radii.height;
456  EXPECT_POINT_NEAR(vertices[i * 2],
457  Point(middle_left - rcos, middle_bottom + rsin))
458  << "vertex " << i << ", angle = " << degrees << ", " //
459  << "bounds = " << bounds << std::endl;
460  EXPECT_POINT_NEAR(vertices[i * 2 + 1],
461  Point(middle_left - rcos, middle_top - rsin))
462  << "vertex " << i << ", angle = " << degrees << ", " //
463  << "bounds = " << bounds << std::endl;
464  EXPECT_POINT_NEAR(vertices[vertex_count - i * 2 - 1],
465  Point(middle_right + rcos, middle_top - rsin))
466  << "vertex " << i << ", angle = " << degrees << ", " //
467  << "bounds = " << bounds << std::endl;
468  EXPECT_POINT_NEAR(vertices[vertex_count - i * 2 - 2],
469  Point(middle_right + rcos, middle_bottom + rsin))
470  << "vertex " << i << ", angle = " << degrees << ", " //
471  << "bounds = " << bounds << std::endl;
472  }
473  };
474 
475  // Both radii spanning the bounds should actually use the circle/ellipse
476  // generator, but their results should match the same math as the round
477  // rect generator.
478  test({}, Rect::MakeXYWH(0, 0, 20, 20), {10, 10});
479 
480  // One radius spanning the bounds, but not the other will not match the
481  // round rect math if the generator transfers to circle/ellipse
482  test({}, Rect::MakeXYWH(0, 0, 20, 20), {10, 5});
483  test({}, Rect::MakeXYWH(0, 0, 20, 20), {5, 10});
484 
485  test({}, Rect::MakeXYWH(0, 0, 20, 30), {2, 2});
486  test({}, Rect::MakeXYWH(0, 0, 30, 20), {2, 2});
487  test({}, Rect::MakeXYWH(5, 10, 20, 30), {2, 3});
488  test({}, Rect::MakeXYWH(16, 7, 30, 20), {2, 3});
489  test(Matrix::MakeScale({500.0, 500.0, 0.0}), Rect::MakeXYWH(5, 10, 30, 20),
490  {2, 3});
491  test(Matrix::MakeScale({500.0, 500.0, 0.0}), Rect::MakeXYWH(5, 10, 20, 30),
492  {2, 3});
493  test(Matrix::MakeScale({0.002, 0.002, 0.0}),
494  Rect::MakeXYWH(5000, 10000, 3000, 2000), {50, 70});
495  test(Matrix::MakeScale({0.002, 0.002, 0.0}),
496  Rect::MakeXYWH(5000, 10000, 2000, 3000), {50, 70});
497 }

References EXPECT_POINT_NEAR, impeller::kPi, impeller::kPiOver2, impeller::kTriangleStrip, impeller::Matrix::MakeScale(), impeller::TRect< Scalar >::MakeXYWH(), and transform.

◆ TEST() [348/360]

impeller::testing::TEST ( TessellatorTest  ,
RoundCapLineTessellationVertices   
)

Definition at line 291 of file tessellator_unittests.cc.

291  {
292  auto tessellator = std::make_shared<Tessellator>();
293 
294  auto test = [&tessellator](const Matrix& transform, const Point& p0,
295  const Point& p1, Scalar radius) {
296  auto generator = tessellator->RoundCapLine(transform, p0, p1, radius);
297  EXPECT_EQ(generator.GetTriangleType(), PrimitiveType::kTriangleStrip);
298 
299  auto vertex_count = generator.GetVertexCount();
300  auto vertices = std::vector<Point>();
301  generator.GenerateVertices([&vertices](const Point& p) { //
302  vertices.push_back(p);
303  });
304  EXPECT_EQ(vertices.size(), vertex_count);
305  ASSERT_EQ(vertex_count % 4, 0u);
306 
307  Point along = p1 - p0;
308  Scalar length = along.GetLength();
309  if (length > 0) {
310  along *= radius / length;
311  } else {
312  along = {radius, 0};
313  }
314  Point across = {-along.y, along.x};
315 
316  auto quadrant_count = vertex_count / 4;
317  for (size_t i = 0; i < quadrant_count; i++) {
318  double angle = kPiOver2 * i / (quadrant_count - 1);
319  double degrees = angle * 180.0 / kPi;
320  // Note that cos(radians(90 degrees)) isn't exactly 0.0 like it should be
321  Point relative_along =
322  along * ((i == quadrant_count - 1) ? 0.0f : cos(angle));
323  Point relative_across = across * sin(angle);
324  EXPECT_POINT_NEAR(vertices[i * 2], //
325  p0 - relative_along + relative_across)
326  << "vertex " << i << ", angle = " << degrees << ", " //
327  << "line = " << p0 << " => " << p1 << ", " //
328  << "radius = " << radius << std::endl;
329  EXPECT_POINT_NEAR(vertices[i * 2 + 1], //
330  p0 - relative_along - relative_across)
331  << "vertex " << i << ", angle = " << degrees << ", " //
332  << "line = " << p0 << " => " << p1 << ", " //
333  << "radius = " << radius << std::endl;
334  EXPECT_POINT_NEAR(vertices[vertex_count - i * 2 - 1], //
335  p1 + relative_along - relative_across)
336  << "vertex " << i << ", angle = " << degrees << ", " //
337  << "line = " << p0 << " => " << p1 << ", " //
338  << "radius = " << radius << std::endl;
339  EXPECT_POINT_NEAR(vertices[vertex_count - i * 2 - 2], //
340  p1 + relative_along + relative_across)
341  << "vertex " << i << ", angle = " << degrees << ", " //
342  << "line = " << p0 << " => " << p1 << ", " //
343  << "radius = " << radius << std::endl;
344  }
345  };
346 
347  // Empty line should actually use the circle generator, but its
348  // results should match the same math as the round cap generator.
349  test({}, {0, 0}, {0, 0}, 10);
350 
351  test({}, {0, 0}, {10, 0}, 2);
352  test({}, {10, 0}, {0, 0}, 2);
353  test({}, {0, 0}, {10, 10}, 2);
354 
355  test(Matrix::MakeScale({500.0, 500.0, 0.0}), {0, 0}, {10, 0}, 2);
356  test(Matrix::MakeScale({500.0, 500.0, 0.0}), {10, 0}, {0, 0}, 2);
357  test(Matrix::MakeScale({500.0, 500.0, 0.0}), {0, 0}, {10, 10}, 2);
358 
359  test(Matrix::MakeScale({0.002, 0.002, 0.0}), {0, 0}, {10, 0}, 2);
360  test(Matrix::MakeScale({0.002, 0.002, 0.0}), {10, 0}, {0, 0}, 2);
361  test(Matrix::MakeScale({0.002, 0.002, 0.0}), {0, 0}, {10, 10}, 2);
362 }

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

impeller::testing::TEST ( TessellatorTest  ,
StrokedCircleTessellationVertices   
)

Definition at line 219 of file tessellator_unittests.cc.

219  {
220  auto tessellator = std::make_shared<Tessellator>();
221 
222  auto test = [&tessellator](const Matrix& transform, const Point& center,
223  Scalar radius, Scalar half_width) {
224  ASSERT_GT(radius, half_width);
225  auto generator =
226  tessellator->StrokedCircle(transform, center, radius, half_width);
227  EXPECT_EQ(generator.GetTriangleType(), PrimitiveType::kTriangleStrip);
228 
229  auto vertex_count = generator.GetVertexCount();
230  auto vertices = std::vector<Point>();
231  generator.GenerateVertices([&vertices](const Point& p) { //
232  vertices.push_back(p);
233  });
234  EXPECT_EQ(vertices.size(), vertex_count);
235  ASSERT_EQ(vertex_count % 4, 0u);
236 
237  auto quadrant_count = vertex_count / 8;
238 
239  // Test outer points first
240  for (size_t i = 0; i < quadrant_count; i++) {
241  double angle = kPiOver2 * i / (quadrant_count - 1);
242  double degrees = angle * 180.0 / kPi;
243  double rsin = sin(angle) * (radius + half_width);
244  // Note that cos(radians(90 degrees)) isn't exactly 0.0 like it should be
245  double rcos =
246  (i == quadrant_count - 1) ? 0.0f : cos(angle) * (radius + half_width);
247  EXPECT_POINT_NEAR(vertices[i * 2],
248  Point(center.x - rcos, center.y - rsin))
249  << "vertex " << i << ", angle = " << degrees << std::endl;
250  EXPECT_POINT_NEAR(vertices[quadrant_count * 2 + i * 2],
251  Point(center.x + rsin, center.y - rcos))
252  << "vertex " << i << ", angle = " << degrees << std::endl;
253  EXPECT_POINT_NEAR(vertices[quadrant_count * 4 + i * 2],
254  Point(center.x + rcos, center.y + rsin))
255  << "vertex " << i << ", angle = " << degrees << std::endl;
256  EXPECT_POINT_NEAR(vertices[quadrant_count * 6 + i * 2],
257  Point(center.x - rsin, center.y + rcos))
258  << "vertex " << i << ", angle = " << degrees << std::endl;
259  }
260 
261  // Then test innerer points
262  for (size_t i = 0; i < quadrant_count; i++) {
263  double angle = kPiOver2 * i / (quadrant_count - 1);
264  double degrees = angle * 180.0 / kPi;
265  double rsin = sin(angle) * (radius - half_width);
266  // Note that cos(radians(90 degrees)) isn't exactly 0.0 like it should be
267  double rcos =
268  (i == quadrant_count - 1) ? 0.0f : cos(angle) * (radius - half_width);
269  EXPECT_POINT_NEAR(vertices[i * 2 + 1],
270  Point(center.x - rcos, center.y - rsin))
271  << "vertex " << i << ", angle = " << degrees << std::endl;
272  EXPECT_POINT_NEAR(vertices[quadrant_count * 2 + i * 2 + 1],
273  Point(center.x + rsin, center.y - rcos))
274  << "vertex " << i << ", angle = " << degrees << std::endl;
275  EXPECT_POINT_NEAR(vertices[quadrant_count * 4 + i * 2 + 1],
276  Point(center.x + rcos, center.y + rsin))
277  << "vertex " << i << ", angle = " << degrees << std::endl;
278  EXPECT_POINT_NEAR(vertices[quadrant_count * 6 + i * 2 + 1],
279  Point(center.x - rsin, center.y + rcos))
280  << "vertex " << i << ", angle = " << degrees << std::endl;
281  }
282  };
283 
284  test({}, {}, 2.0, 1.0);
285  test({}, {}, 2.0, 0.5);
286  test({}, {10, 10}, 2.0, 1.0);
287  test(Matrix::MakeScale({500.0, 500.0, 0.0}), {}, 2.0, 1.0);
288  test(Matrix::MakeScale({0.002, 0.002, 0.0}), {}, 1000.0, 10.0);
289 }

References EXPECT_POINT_NEAR, impeller::kPi, impeller::kPiOver2, impeller::kTriangleStrip, impeller::Matrix::MakeScale(), and transform.

◆ TEST() [350/360]

impeller::testing::TEST ( TessellatorTest  ,
TessellateConvex   
)

Definition at line 84 of file tessellator_unittests.cc.

84  {
85  {
86  std::vector<Point> points;
87  std::vector<uint16_t> indices;
88  // Sanity check simple rectangle.
89  Tessellator::TessellateConvexInternal(
90  PathBuilder{}.AddRect(Rect::MakeLTRB(0, 0, 10, 10)).TakePath(), points,
91  indices, 1.0);
92 
93  // Note: the origin point is repeated but not referenced in the indices
94  // below
95  std::vector<Point> expected = {{0, 0}, {10, 0}, {10, 10}, {0, 10}, {0, 0}};
96  std::vector<uint16_t> expected_indices = {0, 1, 3, 2};
97  EXPECT_EQ(points, expected);
98  EXPECT_EQ(indices, expected_indices);
99  }
100 
101  {
102  std::vector<Point> points;
103  std::vector<uint16_t> indices;
104  Tessellator::TessellateConvexInternal(
105  PathBuilder{}
106  .AddRect(Rect::MakeLTRB(0, 0, 10, 10))
107  .AddRect(Rect::MakeLTRB(20, 20, 30, 30))
108  .TakePath(),
109  points, indices, 1.0);
110 
111  std::vector<Point> expected = {{0, 0}, {10, 0}, {10, 10}, {0, 10},
112  {0, 0}, {20, 20}, {30, 20}, {30, 30},
113  {20, 30}, {20, 20}};
114  std::vector<uint16_t> expected_indices = {0, 1, 3, 2, 2, 5, 5, 6, 8, 7};
115  EXPECT_EQ(points, expected);
116  EXPECT_EQ(indices, expected_indices);
117  }
118 }

References impeller::PathBuilder::AddRect(), impeller::TRect< Scalar >::MakeLTRB(), and impeller::Tessellator::TessellateConvexInternal().

◆ TEST() [351/360]

impeller::testing::TEST ( TessellatorTest  ,
TessellateConvexUnclosedPath   
)

Definition at line 121 of file tessellator_unittests.cc.

121  {
122  std::vector<Point> points;
123  std::vector<uint16_t> indices;
124 
125  // Create a rectangle that lacks an explicit close.
126  Path path = PathBuilder{}
127  .LineTo({100, 0})
128  .LineTo({100, 100})
129  .LineTo({0, 100})
130  .TakePath();
131  Tessellator::TessellateConvexInternal(path, points, indices, 1.0);
132 
133  std::vector<Point> expected = {{0, 0}, {100, 0}, {100, 100}, {0, 100}};
134  std::vector<uint16_t> expected_indices = {0, 1, 3, 2};
135  EXPECT_EQ(points, expected);
136  EXPECT_EQ(indices, expected_indices);
137 }

References impeller::LineTo(), impeller::PathBuilder::LineTo(), and impeller::Tessellator::TessellateConvexInternal().

◆ TEST() [352/360]

impeller::testing::TEST ( TessellatorTest  ,
TessellatorBuilderReturnsCorrectResultStatus   
)

Definition at line 17 of file tessellator_unittests.cc.

17  {
18  // Zero points.
19  {
20  TessellatorLibtess t;
21  auto path = PathBuilder{}.TakePath(FillType::kOdd);
22  TessellatorLibtess::Result result = t.Tessellate(
23  path, 1.0f,
24  [](const float* vertices, size_t vertices_count,
25  const uint16_t* indices, size_t indices_count) { return true; });
26 
27  ASSERT_EQ(result, TessellatorLibtess::Result::kInputError);
28  }
29 
30  // One point.
31  {
32  TessellatorLibtess t;
33  auto path = PathBuilder{}.LineTo({0, 0}).TakePath(FillType::kOdd);
34  TessellatorLibtess::Result result = t.Tessellate(
35  path, 1.0f,
36  [](const float* vertices, size_t vertices_count,
37  const uint16_t* indices, size_t indices_count) { return true; });
38 
39  ASSERT_EQ(result, TessellatorLibtess::Result::kSuccess);
40  }
41 
42  // Two points.
43  {
44  TessellatorLibtess t;
45  auto path = PathBuilder{}.AddLine({0, 0}, {0, 1}).TakePath(FillType::kOdd);
46  TessellatorLibtess::Result result = t.Tessellate(
47  path, 1.0f,
48  [](const float* vertices, size_t vertices_count,
49  const uint16_t* indices, size_t indices_count) { return true; });
50 
51  ASSERT_EQ(result, TessellatorLibtess::Result::kSuccess);
52  }
53 
54  // Many points.
55  {
56  TessellatorLibtess t;
57  PathBuilder builder;
58  for (int i = 0; i < 1000; i++) {
59  auto coord = i * 1.0f;
60  builder.AddLine({coord, coord}, {coord + 1, coord + 1});
61  }
62  auto path = builder.TakePath(FillType::kOdd);
63  TessellatorLibtess::Result result = t.Tessellate(
64  path, 1.0f,
65  [](const float* vertices, size_t vertices_count,
66  const uint16_t* indices, size_t indices_count) { return true; });
67 
68  ASSERT_EQ(result, TessellatorLibtess::Result::kSuccess);
69  }
70 
71  // Closure fails.
72  {
73  TessellatorLibtess t;
74  auto path = PathBuilder{}.AddLine({0, 0}, {0, 1}).TakePath(FillType::kOdd);
75  TessellatorLibtess::Result result = t.Tessellate(
76  path, 1.0f,
77  [](const float* vertices, size_t vertices_count,
78  const uint16_t* indices, size_t indices_count) { return false; });
79 
80  ASSERT_EQ(result, TessellatorLibtess::Result::kInputError);
81  }
82 }

References impeller::PathBuilder::AddLine(), impeller::TessellatorLibtess::kInputError, impeller::kOdd, impeller::TessellatorLibtess::kSuccess, impeller::PathBuilder::LineTo(), impeller::PathBuilder::TakePath(), and impeller::TessellatorLibtess::Tessellate().

◆ TEST() [353/360]

impeller::testing::TEST ( TextureMTL  ,
CreateFromDrawable   
)

Definition at line 21 of file texture_mtl_unittests.mm.

21  {
22  auto device = MTLCreateSystemDefaultDevice();
23  auto layer = [[CAMetalLayer alloc] init];
24  layer.device = device;
25  layer.drawableSize = CGSize{100, 100};
26  layer.pixelFormat = ToMTLPixelFormat(PixelFormat::kB8G8R8A8UNormInt);
27 
28  TextureDescriptor desc;
29  desc.size = {100, 100};
30  desc.format = PixelFormat::kB8G8R8A8UNormInt;
31  auto drawable_future = GetDrawableDeferred(layer);
32  auto drawable_texture =
33  CreateTextureFromDrawableFuture(desc, drawable_future);
34 
35  ASSERT_TRUE(drawable_texture->IsValid());
36  EXPECT_TRUE(drawable_texture->IsDrawable());
37 
38  // Spawn a thread and acquire the drawable in the thread.
39  auto thread = std::thread([&drawable_texture]() {
40  // Force the drawable to be acquired.
41  drawable_texture->GetMTLTexture();
42  });
43  thread.join();
44  // Block until drawable is acquired.
45  EXPECT_TRUE(drawable_future.get() != nil);
46  // Drawable is cached.
47  EXPECT_TRUE(drawable_texture->GetMTLTexture() != nil);
48  // Once more for good measure.
49  EXPECT_TRUE(drawable_texture->GetMTLTexture() != nil);
50 }

References impeller::CreateTextureFromDrawableFuture(), impeller::TextureDescriptor::format, impeller::GetDrawableDeferred(), impeller::kB8G8R8A8UNormInt, impeller::TextureDescriptor::size, and impeller::ToMTLPixelFormat().

◆ TEST() [354/360]

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

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

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  int b = f.a; // NOLINT(clang-analyzer-deadcode.DeadStores)
63  FML_ALLOW_UNUSED_LOCAL(b);
64  f.mtx.UnlockReader();
65 }

References impeller::saturated::b, and impeller::testing::RWFoo::mtx.

◆ TEST() [357/360]

impeller::testing::TEST ( ThreadTest  ,
CanCreateRWMutexLock   
)

Definition at line 67 of file base_unittests.cc.

67  {
68  RWFoo f = {};
69 
70  // f.a = 100; <--- Static analysis error.
71  {
72  auto write_lock = WriterLock{f.mtx};
73  f.a = 100;
74  }
75 
76  // int b = f.a; <--- Static analysis error.
77  {
78  auto read_lock = ReaderLock(f.mtx);
79  int b = f.a; // NOLINT(clang-analyzer-deadcode.DeadStores)
80  FML_ALLOW_UNUSED_LOCAL(b);
81  }
82 
83  // f.mtx.UnlockReader(); <--- Static analysis error.
84 }

References impeller::saturated::b, and impeller::testing::RWFoo::mtx.

◆ TEST() [358/360]

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

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

impeller::testing::TEST ( TypographerTest  ,
RectanglePackerFillsRows   
)

Definition at line 398 of file typographer_unittests.cc.

398  {
399  auto skyline = RectanglePacker::Factory(257, 256);
400 
401  // Fill up the first row.
402  IPoint16 loc;
403  for (auto i = 0u; i < 16; i++) {
404  skyline->AddRect(16, 16, &loc);
405  }
406  // Last rectangle still in first row.
407  EXPECT_EQ(loc.x(), 256 - 16);
408  EXPECT_EQ(loc.y(), 0);
409 
410  // Fill up second row.
411  for (auto i = 0u; i < 16; i++) {
412  skyline->AddRect(16, 16, &loc);
413  }
414 
415  EXPECT_EQ(loc.x(), 256 - 16);
416  EXPECT_EQ(loc.y(), 16);
417 }

References impeller::RectanglePacker::Factory(), impeller::IPoint16::x(), and impeller::IPoint16::y().

◆ TEST_F()

impeller::testing::TEST_F ( GoldenTests  ,
ConicalGradient   
)

Definition at line 72 of file golden_tests.cc.

72  {
73  Canvas canvas;
74  Paint paint;
75 
76  paint.color_source = ColorSource::MakeConicalGradient(
77  {125, 125}, 125, {Color(1.0, 0.0, 0.0, 1.0), Color(0.0, 0.0, 1.0, 1.0)},
78  {0, 1}, {180, 180}, 0, Entity::TileMode::kClamp, {});
79 
80  paint.stroke_width = 0.0;
81  paint.style = Paint::Style::kFill;
82  canvas.DrawRect(Rect::MakeXYWH(10, 10, 250, 250), paint);
83  Picture picture = canvas.EndRecordingAsPicture();
84 
85  auto aiks_context =
86  AiksContext(Screenshotter().GetPlayground().GetContext(), nullptr);
87  auto screenshot = Screenshotter().MakeScreenshot(aiks_context, picture);
88  ASSERT_TRUE(SaveScreenshot(std::move(screenshot)));
89 }

References impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::Entity::kClamp, impeller::Paint::kFill, impeller::ColorSource::MakeConicalGradient(), impeller::testing::Screenshotter::MakeScreenshot(), impeller::TRect< Scalar >::MakeXYWH(), and paint.

◆ TEST_P() [1/456]

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

Definition at line 371 of file aiks_path_unittests.cc.

371  {
372  Canvas canvas;
373  canvas.Scale(GetContentScale());
374 
375  Paint paint;
376  paint.color = Color::Red();
377  std::vector<Color> colors = {Color{1.0, 0.0, 0.0, 1.0},
378  Color{0.0, 0.0, 0.0, 1.0}};
379  std::vector<Scalar> stops = {0.0, 1.0};
380  paint.color_source = ColorSource::MakeSweepGradient(
381  {100, 100}, Degrees(45), Degrees(135), std::move(colors),
382  std::move(stops), Entity::TileMode::kMirror, {});
383  paint.mask_blur_descriptor = Paint::MaskBlurDescriptor{
384  .style = FilterContents::BlurStyle::kNormal,
385  .sigma = Sigma(20),
386  };
387 
388  PathBuilder builder;
389  builder.AddArc(Rect::MakeXYWH(10, 10, 100, 100), Degrees(0), Degrees(0),
390  false);
391  canvas.DrawPath(builder.TakePath(), paint);
392 
393  // Check that this empty picture can be created without crashing.
394  canvas.EndRecordingAsPicture();
395 }

References impeller::PathBuilder::AddArc(), impeller::Canvas::DrawPath(), impeller::Canvas::EndRecordingAsPicture(), impeller::Entity::kMirror, impeller::FilterContents::kNormal, impeller::ColorSource::MakeSweepGradient(), impeller::TRect< Scalar >::MakeXYWH(), paint, impeller::Color::Red(), impeller::Canvas::Scale(), impeller::Paint::MaskBlurDescriptor::style, and impeller::PathBuilder::TakePath().

◆ TEST_P() [2/456]

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

Definition at line 157 of file aiks_blend_unittests.cc.

157  {
158  EXPECT_EQ(GetContext()->GetCapabilities()->GetDefaultColorFormat(),
159  PixelFormat::kB10G10R10A10XR);
160  auto texture = CreateTextureForFixture("airplane.jpg",
161  /*enable_mipmapping=*/true);
162 
163  Canvas canvas;
164  canvas.Scale(GetContentScale());
165  canvas.DrawPaint({.color = Color(0.1, 0.2, 0.1, 1.0)});
166  canvas.SaveLayer({
167  .color_filter =
168  ColorFilter::MakeBlend(BlendMode::kPlus, Color(Vector4{1, 0, 0, 1})),
169  });
170  Paint paint;
171  paint.color = Color::Red();
172  canvas.DrawRect(Rect::MakeXYWH(100, 100, 400, 400), paint);
173  paint.color = Color::White();
174  canvas.DrawImageRect(
175  std::make_shared<Image>(texture), Rect::MakeSize(texture->GetSize()),
176  Rect::MakeXYWH(100, 100, 400, 400).Expand(-100, -100), paint);
177  canvas.Restore();
178  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
179 }

References impeller::Canvas::DrawImageRect(), impeller::Canvas::DrawPaint(), impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::TRect< T >::Expand(), impeller::kB10G10R10A10XR, impeller::kPlus, impeller::ColorFilter::MakeBlend(), impeller::TRect< Scalar >::MakeSize(), impeller::TRect< Scalar >::MakeXYWH(), paint, impeller::Color::Red(), impeller::Canvas::Restore(), impeller::Canvas::SaveLayer(), impeller::Canvas::Scale(), and impeller::Color::White().

◆ TEST_P() [3/456]

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

Definition at line 134 of file aiks_blend_unittests.cc.

134  {
135  EXPECT_EQ(GetContext()->GetCapabilities()->GetDefaultColorFormat(),
136  PixelFormat::kB10G10R10A10XR);
137  auto texture = CreateTextureForFixture("airplane.jpg",
138  /*enable_mipmapping=*/true);
139 
140  Canvas canvas;
141  canvas.Scale(GetContentScale());
142  canvas.DrawPaint({.color = Color(0.9, 1.0, 0.9, 1.0)});
143  canvas.SaveLayer({});
144  Paint paint;
145  paint.blend_mode = BlendMode::kPlus;
146  paint.color = Color::Red();
147  canvas.DrawRect(Rect::MakeXYWH(100, 100, 400, 400), paint);
148  paint.color = Color::White();
149  canvas.DrawImageRect(
150  std::make_shared<Image>(texture), Rect::MakeSize(texture->GetSize()),
151  Rect::MakeXYWH(100, 100, 400, 400).Expand(-100, -100), paint);
152  canvas.Restore();
153  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
154 }

References impeller::Canvas::DrawImageRect(), impeller::Canvas::DrawPaint(), impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::TRect< T >::Expand(), impeller::kB10G10R10A10XR, impeller::kPlus, impeller::TRect< Scalar >::MakeSize(), impeller::TRect< Scalar >::MakeXYWH(), paint, impeller::Color::Red(), impeller::Canvas::Restore(), impeller::Canvas::SaveLayer(), impeller::Canvas::Scale(), and impeller::Color::White().

◆ TEST_P() [4/456]

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

Definition at line 43 of file aiks_blend_unittests.cc.

43  {
44  Canvas canvas;
45  Paint paint;
46 
47  paint.color = Color::Red();
48  canvas.DrawPaint(paint);
49 
50  paint.blend_mode = BlendMode::kSourceOver;
51  canvas.SaveLayer(paint);
52 
53  paint.color = Color::White();
54  canvas.DrawRect(Rect::MakeXYWH(100, 100, 400, 400), paint);
55 
56  paint.blend_mode = BlendMode::kSource;
57  canvas.SaveLayer(paint);
58 
59  paint.color = Color::Blue();
60  canvas.DrawRect(Rect::MakeXYWH(200, 200, 200, 200), paint);
61 
62  canvas.Restore();
63  canvas.Restore();
64 
65  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
66 }

References impeller::Color::Blue(), impeller::Canvas::DrawPaint(), impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::kSource, impeller::kSourceOver, impeller::TRect< Scalar >::MakeXYWH(), paint, impeller::Color::Red(), impeller::Canvas::Restore(), impeller::Canvas::SaveLayer(), and impeller::Color::White().

◆ TEST_P() [5/456]

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

Definition at line 201 of file aiks_blur_unittests.cc.

201  {
202  Scalar sigma = 47.6;
203  auto callback = [&](AiksContext& renderer) -> std::optional<Picture> {
204  if (AiksTest::ImGuiBegin("Controls", nullptr,
205  ImGuiWindowFlags_AlwaysAutoResize)) {
206  ImGui::SliderFloat("Sigma", &sigma, 0, 50);
207  ImGui::End();
208  }
209  Canvas canvas;
210  canvas.Scale(GetContentScale());
211  canvas.DrawPaint({});
212  Paint blur = {
213  .color = Color::Green(),
214  .mask_blur_descriptor =
215  Paint::MaskBlurDescriptor{
216  .style = FilterContents::BlurStyle::kNormal,
217  .sigma = Sigma(sigma),
218  },
219  };
220  canvas.DrawRect(Rect::MakeXYWH(300, 300, 200, 200), blur);
221  return canvas.EndRecordingAsPicture();
222  };
223 
224  ASSERT_TRUE(OpenPlaygroundHere(callback));
225 }

References impeller::Paint::color, impeller::Canvas::DrawPaint(), impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::Green(), impeller::AiksPlayground::ImGuiBegin(), impeller::FilterContents::kNormal, impeller::TRect< Scalar >::MakeXYWH(), impeller::Canvas::Scale(), and impeller::Paint::MaskBlurDescriptor::style.

◆ TEST_P() [6/456]

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

Definition at line 227 of file aiks_blur_unittests.cc.

227  {
228  Canvas canvas;
229  canvas.Scale(GetContentScale());
230 
231  auto paint_lines = [&canvas](Scalar dx, Scalar dy, Paint paint) {
232  auto draw_line = [&canvas, &paint](Point a, Point b) {
233  canvas.DrawPath(PathBuilder{}.AddLine(a, b).TakePath(), paint);
234  };
235  paint.stroke_width = 5;
236  paint.style = Paint::Style::kStroke;
237  draw_line(Point(dx + 100, dy + 100), Point(dx + 200, dy + 200));
238  draw_line(Point(dx + 100, dy + 200), Point(dx + 200, dy + 100));
239  draw_line(Point(dx + 150, dy + 100), Point(dx + 200, dy + 150));
240  draw_line(Point(dx + 100, dy + 150), Point(dx + 150, dy + 200));
241  };
242 
243  AiksContext renderer(GetContext(), nullptr);
244  Canvas recorder_canvas;
245  for (int x = 0; x < 5; ++x) {
246  for (int y = 0; y < 5; ++y) {
247  Rect rect = Rect::MakeXYWH(x * 20, y * 20, 20, 20);
248  Paint paint{.color =
249  ((x + y) & 1) == 0 ? Color::Yellow() : Color::Blue()};
250  recorder_canvas.DrawRect(rect, paint);
251  }
252  }
253  Picture picture = recorder_canvas.EndRecordingAsPicture();
254  std::shared_ptr<Texture> texture =
255  picture.ToImage(renderer, ISize{100, 100})->GetTexture();
256 
257  ColorSource image_source = ColorSource::MakeImage(
258  texture, Entity::TileMode::kRepeat, Entity::TileMode::kRepeat, {}, {});
259  std::shared_ptr<ImageFilter> blur_filter = ImageFilter::MakeBlur(
260  Sigma(5), Sigma(5), FilterContents::BlurStyle::kNormal,
261  Entity::TileMode::kDecal);
262  canvas.DrawRect(Rect::MakeLTRB(0, 0, 300, 600),
263  Paint{.color = Color::DarkGreen()});
264  canvas.DrawRect(Rect::MakeLTRB(100, 100, 200, 200),
265  Paint{.color_source = image_source});
266  canvas.DrawRect(Rect::MakeLTRB(300, 0, 600, 600),
267  Paint{.color = Color::Red()});
268  canvas.DrawRect(
269  Rect::MakeLTRB(400, 100, 500, 200),
270  Paint{.color_source = image_source, .image_filter = blur_filter});
271  paint_lines(0, 300, Paint{.color_source = image_source});
272  paint_lines(300, 300,
273  Paint{.color_source = image_source, .image_filter = blur_filter});
274  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
275 }

References impeller::PathBuilder::AddLine(), impeller::saturated::b, impeller::Color::Blue(), impeller::Paint::color, impeller::Paint::color_source, impeller::Color::DarkGreen(), impeller::Canvas::DrawPath(), impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::Entity::kDecal, impeller::FilterContents::kNormal, impeller::Entity::kRepeat, impeller::Paint::kStroke, impeller::ImageFilter::MakeBlur(), impeller::ColorSource::MakeImage(), impeller::TRect< Scalar >::MakeLTRB(), impeller::TRect< Scalar >::MakeXYWH(), paint, impeller::Color::Red(), impeller::Canvas::Scale(), impeller::PathBuilder::TakePath(), impeller::Picture::ToImage(), and impeller::Color::Yellow().

◆ TEST_P() [7/456]

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

Definition at line 153 of file aiks_dl_vertices_unittests.cc.

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

References paint.

◆ TEST_P() [8/456]

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

Definition at line 142 of file aiks_path_unittests.cc.

142  {
143  Canvas canvas;
144 
145  // Starting at (50, 50), draw lines from:
146  // 1. (50, height)
147  // 2. (width, height)
148  // 3. (width, 50)
149  PathBuilder builder;
150  builder.MoveTo({50, 50});
151  builder.LineTo({50, 100});
152  builder.LineTo({100, 100});
153  builder.LineTo({100, 50});
154 
155  Paint paint;
156  paint.color = Color::Red();
157  paint.style = Paint::Style::kStroke;
158  paint.stroke_width = 10;
159 
160  canvas.DrawPath(builder.TakePath(), paint);
161 
162  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
163 }

References impeller::Canvas::DrawPath(), impeller::Canvas::EndRecordingAsPicture(), impeller::Paint::kStroke, impeller::PathBuilder::LineTo(), impeller::PathBuilder::MoveTo(), paint, impeller::Color::Red(), and impeller::PathBuilder::TakePath().

◆ TEST_P() [9/456]

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

Definition at line 165 of file aiks_path_unittests.cc.

165  {
166  Canvas canvas;
167 
168  // Draw a stroked path that is explicitly closed to verify
169  // It doesn't become a rectangle.
170  PathBuilder builder;
171  builder.MoveTo({50, 50});
172  builder.LineTo({520, 120});
173  builder.LineTo({300, 310});
174  builder.LineTo({100, 50});
175  builder.Close();
176 
177  Paint paint;
178  paint.color = Color::Red();
179  paint.style = Paint::Style::kStroke;
180  paint.stroke_width = 10;
181 
182  canvas.DrawPath(builder.TakePath(), paint);
183 
184  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
185 }

References impeller::PathBuilder::Close(), impeller::Canvas::DrawPath(), impeller::Canvas::EndRecordingAsPicture(), impeller::Paint::kStroke, impeller::PathBuilder::LineTo(), impeller::PathBuilder::MoveTo(), paint, impeller::Color::Red(), and impeller::PathBuilder::TakePath().

◆ TEST_P() [10/456]

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

Definition at line 351 of file aiks_path_unittests.cc.

351  {
352  PathBuilder builder = {};
353  for (auto i = 0; i < 10; i++) {
354  if (i % 2 == 0) {
355  builder.AddCircle(Point(100 + 50 * i, 100 + 50 * i), 100);
356  } else {
357  builder.MoveTo({100.f + 50.f * i - 100, 100.f + 50.f * i});
358  builder.LineTo({100.f + 50.f * i, 100.f + 50.f * i - 100});
359  builder.LineTo({100.f + 50.f * i - 100, 100.f + 50.f * i - 100});
360  builder.Close();
361  }
362  }
363  builder.SetConvexity(Convexity::kConvex);
364 
365  Canvas canvas;
366  canvas.DrawPath(builder.TakePath(), {.color = Color::Red().WithAlpha(0.4)});
367 
368  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
369 }

References impeller::PathBuilder::AddCircle(), impeller::PathBuilder::Close(), impeller::Canvas::DrawPath(), impeller::Canvas::EndRecordingAsPicture(), impeller::kConvex, impeller::PathBuilder::LineTo(), impeller::PathBuilder::MoveTo(), impeller::PathBuilder::SetConvexity(), and impeller::PathBuilder::TakePath().

◆ TEST_P() [11/456]

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

Definition at line 855 of file aiks_unittests.cc.

855  {
856  Canvas canvas;
857  canvas.Scale(Vector2(0.2, 0.2));
858  canvas.DrawPaint({.color = Color::MediumTurquoise()});
859  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
860 }

References impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::MediumTurquoise(), and impeller::Canvas::Scale().

◆ TEST_P() [12/456]

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

Definition at line 862 of file aiks_unittests.cc.

862  {
863  Canvas canvas;
864  canvas.Scale(Vector2(0.2, 0.2));
865  canvas.DrawPaint({.color = Color::MediumTurquoise()});
866  canvas.DrawPaint({.color = Color::Color::OrangeRed().WithAlpha(0.5)});
867  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
868 }

References impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::MediumTurquoise(), and impeller::Canvas::Scale().

◆ TEST_P() [13/456]

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

Definition at line 524 of file aiks_blend_unittests.cc.

524  {
525  auto modes = GetBlendModeSelection();
526 
527  auto callback = [&](AiksContext& renderer) -> std::optional<Picture> {
528  static Color background = Color::MediumTurquoise();
529  static Color foreground = Color::Color::OrangeRed().WithAlpha(0.5);
530  static int current_blend_index = 3;
531 
532  if (AiksTest::ImGuiBegin("Controls", nullptr,
533  ImGuiWindowFlags_AlwaysAutoResize)) {
534  ImGui::ColorEdit4("Background", reinterpret_cast<float*>(&background));
535  ImGui::ColorEdit4("Foreground", reinterpret_cast<float*>(&foreground));
536  ImGui::ListBox("Blend mode", &current_blend_index,
537  modes.blend_mode_names.data(),
538  modes.blend_mode_names.size());
539  ImGui::End();
540  }
541 
542  Canvas canvas;
543  canvas.Scale(Vector2(0.2, 0.2));
544  canvas.DrawPaint({.color = background});
545  canvas.DrawPaint(
546  {.color = foreground,
547  .blend_mode = static_cast<BlendMode>(current_blend_index)});
548  return canvas.EndRecordingAsPicture();
549  };
550  ASSERT_TRUE(OpenPlaygroundHere(callback));
551 }

References impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), GetBlendModeSelection(), impeller::AiksPlayground::ImGuiBegin(), impeller::Color::MediumTurquoise(), impeller::Canvas::Scale(), and impeller::Color::WithAlpha().

◆ TEST_P() [14/456]

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

Definition at line 68 of file aiks_blend_unittests.cc.

68  {
69  Canvas canvas;
70  canvas.Scale(Vector2(0.2, 0.2));
71  canvas.DrawPaint({.color = Color::MediumTurquoise()});
72  canvas.DrawPaint({.color = Color::Color::OrangeRed().WithAlpha(0.5),
73  .blend_mode = BlendMode::kHue});
74  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
75 }

References impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), impeller::kHue, impeller::Color::MediumTurquoise(), and impeller::Canvas::Scale().

◆ TEST_P() [15/456]

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

Definition at line 2705 of file aiks_unittests.cc.

2705  {
2706  // Avoiding `GetSecondsElapsed()` to reduce risk of golden flakiness.
2707  int time = 0;
2708  auto callback = [&](AiksContext& renderer) -> std::optional<Picture> {
2709  Canvas canvas;
2710 
2711  canvas.Save();
2712  {
2713  canvas.Translate({300, 300});
2714 
2715  // 1. Draw/restore a clip before drawing the image, which will get drawn
2716  // to the depth buffer behind the image.
2717  canvas.Save();
2718  {
2719  canvas.DrawPaint({.color = Color::Green()});
2720  canvas.ClipRect(Rect::MakeLTRB(-180, -180, 180, 180),
2721  Entity::ClipOperation::kDifference);
2722  canvas.DrawPaint({.color = Color::Black()});
2723  }
2724  canvas.Restore(); // Restore rectangle difference clip.
2725 
2726  canvas.Save();
2727  {
2728  // 2. Draw an oval clip that applies to the image, which will get drawn
2729  // in front of the image on the depth buffer.
2730  canvas.ClipOval(Rect::MakeLTRB(-200, -200, 200, 200));
2731 
2732  // 3. Draw the rotating image with a perspective transform.
2733  canvas.Transform(
2734  Matrix(1.0, 0.0, 0.0, 0.0, //
2735  0.0, 1.0, 0.0, 0.0, //
2736  0.0, 0.0, 1.0, 0.003, //
2737  0.0, 0.0, 0.0, 1.0) * //
2738  Matrix::MakeRotationY({Radians{-1.0f + (time++ / 60.0f)}}));
2739  auto image =
2740  std::make_shared<Image>(CreateTextureForFixture("airplane.jpg"));
2741  canvas.DrawImage(image, -Point(image->GetSize()) / 2, {});
2742  }
2743  canvas.Restore(); // Restore oval intersect clip.
2744 
2745  // 4. Draw a semi-translucent blue circle atop all previous draws.
2746  canvas.DrawCircle({}, 230, {.color = Color::Blue().WithAlpha(0.4)});
2747  }
2748  canvas.Restore(); // Restore translation.
2749 
2750  return canvas.EndRecordingAsPicture();
2751  };
2752  ASSERT_TRUE(OpenPlaygroundHere(callback));
2753 }

References impeller::Color::Black(), impeller::Color::Blue(), impeller::Canvas::ClipOval(), impeller::Canvas::ClipRect(), impeller::Canvas::DrawCircle(), impeller::Canvas::DrawImage(), impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::Green(), impeller::Entity::kDifference, impeller::TRect< Scalar >::MakeLTRB(), impeller::Matrix::MakeRotationY(), impeller::Canvas::Restore(), impeller::Canvas::Save(), impeller::Canvas::Transform(), impeller::Canvas::Translate(), and impeller::Color::WithAlpha().

◆ TEST_P() [16/456]

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

Definition at line 2243 of file aiks_unittests.cc.

2243  {
2244  std::vector<Point> points = {
2245  {0, 0}, //
2246  {100, 100}, //
2247  {100, 0}, //
2248  {0, 100}, //
2249  {0, 0}, //
2250  {48, 48}, //
2251  {52, 52}, //
2252  };
2253  std::vector<PointStyle> caps = {
2254  PointStyle::kRound,
2255  PointStyle::kSquare,
2256  };
2257  Paint paint;
2258  paint.color = Color::Yellow().WithAlpha(0.5);
2259 
2260  Paint background;
2261  background.color = Color::Black();
2262 
2263  Canvas canvas;
2264  canvas.DrawPaint(background);
2265  canvas.Translate({200, 200});
2266  canvas.DrawPoints(points, 10, paint, PointStyle::kRound);
2267  canvas.Translate({150, 0});
2268  canvas.DrawPoints(points, 10, paint, PointStyle::kSquare);
2269 
2270  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2271 }

References impeller::Color::Black(), impeller::Paint::color, impeller::Canvas::DrawPaint(), impeller::Canvas::DrawPoints(), impeller::Canvas::EndRecordingAsPicture(), impeller::kRound, impeller::kSquare, paint, impeller::Canvas::Translate(), impeller::Color::WithAlpha(), and impeller::Color::Yellow().

◆ TEST_P() [17/456]

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

Definition at line 2273 of file aiks_unittests.cc.

2273  {
2274  auto texture = CreateTextureForFixture("table_mountain_nx.png",
2275  /*enable_mipmapping=*/true);
2276 
2277  std::vector<Point> points = {
2278  {0, 0}, //
2279  {100, 100}, //
2280  {100, 0}, //
2281  {0, 100}, //
2282  {0, 0}, //
2283  {48, 48}, //
2284  {52, 52}, //
2285  };
2286  std::vector<PointStyle> caps = {
2287  PointStyle::kRound,
2288  PointStyle::kSquare,
2289  };
2290  Paint paint;
2291  paint.color_source = ColorSource::MakeImage(texture, Entity::TileMode::kClamp,
2292  Entity::TileMode::kClamp, {}, {});
2293 
2294  Canvas canvas;
2295  canvas.Translate({200, 200});
2296  canvas.DrawPoints(points, 100, paint, PointStyle::kRound);
2297  canvas.Translate({150, 0});
2298  canvas.DrawPoints(points, 100, paint, PointStyle::kSquare);
2299 
2300  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2301 }

References impeller::Entity::kClamp, impeller::kRound, impeller::kSquare, impeller::ColorSource::MakeImage(), paint, and impeller::Canvas::Translate().

◆ TEST_P() [18/456]

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

Definition at line 385 of file aiks_unittests.cc.

385  {
386  Canvas recorder_canvas;
387 
388  Canvas canvas;
389  AiksContext renderer(GetContext(), nullptr);
390  Paint paint;
391  paint.color = Color::BlackTransparent();
392  canvas.DrawPaint(paint);
393  Picture picture = recorder_canvas.EndRecordingAsPicture();
394  auto image = picture.ToImage(renderer, ISize{1000, 1000});
395  if (image) {
396  canvas.DrawImage(image, Point(), Paint());
397  paint.color = Color{0.1, 0.1, 0.1, 0.2};
398  canvas.DrawRect(Rect::MakeSize(ISize{1000, 1000}), paint);
399  }
400 
401  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
402 }

References impeller::Color::BlackTransparent(), impeller::Canvas::DrawImage(), impeller::Canvas::DrawPaint(), impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::TRect< Scalar >::MakeSize(), paint, and impeller::Picture::ToImage().

◆ TEST_P() [19/456]

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

Definition at line 445 of file aiks_unittests.cc.

445  {
446  Canvas canvas;
447 
448  Paint red;
449  red.color = Color::Red();
450 
451  canvas.DrawCircle({250, 250}, 125, red);
452 
453  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
454 }

References impeller::Paint::color, impeller::Canvas::DrawCircle(), impeller::Canvas::EndRecordingAsPicture(), and impeller::Color::Red().

◆ TEST_P() [20/456]

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

Definition at line 468 of file aiks_unittests.cc.

468  {
469  Canvas canvas;
470 
471  Paint red;
472  red.color = Color::Red();
473 
474  Paint green;
475  green.color = Color::Green();
476 
477  Paint blue;
478  blue.color = Color::Blue();
479 
480  Paint save;
481  save.color = Color::Black();
482 
483  canvas.SaveLayer(save, Rect::MakeXYWH(0, 0, 50, 50));
484 
485  canvas.DrawRect(Rect::MakeXYWH(0, 0, 100, 100), red);
486  canvas.DrawRect(Rect::MakeXYWH(10, 10, 100, 100), green);
487  canvas.DrawRect(Rect::MakeXYWH(20, 20, 100, 100), blue);
488 
489  canvas.Restore();
490 
491  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
492 }

References impeller::Color::Black(), impeller::Color::Blue(), impeller::Paint::color, impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::Green(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Color::Red(), impeller::Canvas::Restore(), and impeller::Canvas::SaveLayer().

◆ TEST_P() [21/456]

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

Definition at line 494 of file aiks_unittests.cc.

495  {
496  Canvas canvas;
497 
498  Paint red;
499  red.color = Color::Red();
500 
501  Paint green;
502  green.color = Color::Green();
503 
504  Paint blue;
505  blue.color = Color::Blue();
506 
507  Paint save;
508  save.color = Color::Black().WithAlpha(0.5);
509 
510  canvas.SaveLayer(save, Rect::MakeXYWH(0, 0, 100000, 100000));
511 
512  canvas.DrawRect(Rect::MakeXYWH(0, 0, 100, 100), red);
513  canvas.DrawRect(Rect::MakeXYWH(10, 10, 100, 100), green);
514  canvas.DrawRect(Rect::MakeXYWH(20, 20, 100, 100), blue);
515 
516  canvas.Restore();
517 
518  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
519 }

References impeller::Color::Black(), impeller::Color::Blue(), impeller::Paint::color, impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::Green(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Color::Red(), impeller::Canvas::Restore(), impeller::Canvas::SaveLayer(), and impeller::Color::WithAlpha().

◆ TEST_P() [22/456]

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

Definition at line 456 of file aiks_unittests.cc.

456  {
457  Canvas canvas;
458 
459  Paint red;
460  red.color = Color::Red();
461 
462  canvas.Skew(2, 5);
463  canvas.DrawRect(Rect::MakeXYWH(0, 0, 100, 100), red);
464 
465  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
466 }

References impeller::Paint::color, impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Color::Red(), and impeller::Canvas::Skew().

◆ TEST_P() [23/456]

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

Definition at line 359 of file aiks_unittests.cc.

359  {
360  Canvas recorder_canvas;
361  Paint paint;
362  paint.color = Color{0.9568, 0.2627, 0.2118, 1.0};
363  recorder_canvas.DrawRect(Rect::MakeXYWH(100.0, 100.0, 600, 600), paint);
364  paint.color = Color{0.1294, 0.5882, 0.9529, 1.0};
365  recorder_canvas.DrawRect(Rect::MakeXYWH(200.0, 200.0, 600, 600), paint);
366 
367  Canvas canvas;
368  AiksContext renderer(GetContext(), nullptr);
369  paint.color = Color::BlackTransparent();
370  canvas.DrawPaint(paint);
371  Picture picture = recorder_canvas.EndRecordingAsPicture();
372  auto image = picture.ToImage(renderer, ISize{1000, 1000});
373  if (image) {
374  canvas.DrawImage(image, Point(), Paint());
375  paint.color = Color{0.1, 0.1, 0.1, 0.2};
376  canvas.DrawRect(Rect::MakeSize(ISize{1000, 1000}), paint);
377  }
378 
379  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
380 }

References impeller::Color::BlackTransparent(), impeller::Canvas::DrawImage(), impeller::Canvas::DrawPaint(), impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::TRect< Scalar >::MakeSize(), impeller::TRect< Scalar >::MakeXYWH(), paint, and impeller::Picture::ToImage().

◆ TEST_P() [24/456]

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

Definition at line 21 of file aiks_blend_unittests.cc.

21  {
22  Canvas canvas;
23 
24  Rect layer_rect = Rect::MakeXYWH(0, 0, 500, 500);
25  canvas.ClipRect(layer_rect);
26 
27  canvas.SaveLayer(
28  {
29  .color_filter = ColorFilter::MakeBlend(BlendMode::kDifference,
30  Color(0, 1, 0, 0.5)),
31  },
32  layer_rect);
33 
34  Paint paint;
35  canvas.DrawPaint({.color = Color::Black()});
36  canvas.DrawRect(Rect::MakeXYWH(100, 100, 300, 300),
37  {.color = Color::White()});
38  canvas.Restore();
39 
40  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
41 }

References impeller::Color::Black(), impeller::Canvas::ClipRect(), impeller::Canvas::DrawPaint(), impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::kDifference, impeller::ColorFilter::MakeBlend(), impeller::TRect< Scalar >::MakeXYWH(), paint, impeller::Canvas::Restore(), impeller::Canvas::SaveLayer(), and impeller::Color::White().

◆ TEST_P() [25/456]

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

Definition at line 102 of file aiks_blur_unittests.cc.

102  {
103  Canvas canvas;
104  canvas.DrawCircle({100, 100}, 50, {.color = Color::CornflowerBlue()});
105  canvas.DrawCircle({300, 200}, 100, {.color = Color::GreenYellow()});
106  canvas.DrawCircle({140, 170}, 75, {.color = Color::DarkMagenta()});
107  canvas.DrawCircle({180, 120}, 100, {.color = Color::OrangeRed()});
108  canvas.ClipRRect(Rect::MakeLTRB(75, 50, 375, 275), {20, 20});
109  canvas.SaveLayer({.blend_mode = BlendMode::kSource}, std::nullopt,
110  ImageFilter::MakeBlur(Sigma(30.0), Sigma(30.0),
111  FilterContents::BlurStyle::kNormal,
112  Entity::TileMode::kClamp));
113  canvas.Restore();
114 
115  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
116 }

References impeller::Canvas::ClipRRect(), impeller::Color::CornflowerBlue(), impeller::Color::DarkMagenta(), impeller::Canvas::DrawCircle(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::GreenYellow(), impeller::Entity::kClamp, impeller::FilterContents::kNormal, impeller::kSource, impeller::ImageFilter::MakeBlur(), impeller::TRect< Scalar >::MakeLTRB(), impeller::Color::OrangeRed(), impeller::Canvas::Restore(), and impeller::Canvas::SaveLayer().

◆ TEST_P() [26/456]

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

Definition at line 118 of file aiks_blur_unittests.cc.

118  {
119  Canvas canvas;
120  canvas.DrawCircle({400, 400}, 300, {.color = Color::Green()});
121  canvas.SaveLayer({.blend_mode = BlendMode::kSource}, std::nullopt,
122  ImageFilter::MakeBlur(Sigma(999999), Sigma(999999),
123  FilterContents::BlurStyle::kNormal,
124  Entity::TileMode::kClamp));
125  canvas.Restore();
126 
127  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
128 }

References impeller::Canvas::DrawCircle(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::Green(), impeller::Entity::kClamp, impeller::FilterContents::kNormal, impeller::kSource, impeller::ImageFilter::MakeBlur(), impeller::Canvas::Restore(), and impeller::Canvas::SaveLayer().

◆ TEST_P() [27/456]

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

Definition at line 78 of file aiks_blur_unittests.cc.

78  {
79  auto callback = [&](AiksContext& renderer) -> std::optional<Picture> {
80  static PlaygroundPoint point_a(Point(50, 50), 30, Color::White());
81  static PlaygroundPoint point_b(Point(300, 200), 30, Color::White());
82  auto [a, b] = DrawPlaygroundLine(point_a, point_b);
83 
84  Canvas canvas;
85  canvas.DrawCircle({100, 100}, 50, {.color = Color::CornflowerBlue()});
86  canvas.DrawCircle({300, 200}, 100, {.color = Color::GreenYellow()});
87  canvas.DrawCircle({140, 170}, 75, {.color = Color::DarkMagenta()});
88  canvas.DrawCircle({180, 120}, 100, {.color = Color::OrangeRed()});
89  canvas.ClipRRect(Rect::MakeLTRB(a.x, a.y, b.x, b.y), {20, 20});
90  canvas.SaveLayer({.blend_mode = BlendMode::kSource}, std::nullopt,
91  ImageFilter::MakeBlur(Sigma(20.0), Sigma(20.0),
92  FilterContents::BlurStyle::kNormal,
93  Entity::TileMode::kClamp));
94  canvas.Restore();
95 
96  return canvas.EndRecordingAsPicture();
97  };
98 
99  ASSERT_TRUE(OpenPlaygroundHere(callback));
100 }

References impeller::saturated::b, impeller::Canvas::ClipRRect(), impeller::Color::CornflowerBlue(), impeller::Color::DarkMagenta(), impeller::Canvas::DrawCircle(), impeller::DrawPlaygroundLine(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::GreenYellow(), impeller::Entity::kClamp, impeller::FilterContents::kNormal, impeller::kSource, impeller::ImageFilter::MakeBlur(), impeller::TRect< Scalar >::MakeLTRB(), impeller::Color::OrangeRed(), impeller::Canvas::Restore(), impeller::Canvas::SaveLayer(), and impeller::Color::White().

◆ TEST_P() [28/456]

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

Definition at line 2755 of file aiks_unittests.cc.

2755  {
2756  Canvas canvas;
2757  Paint paint;
2758 
2759  canvas.Scale(GetContentScale());
2760 
2761  // Draw something interesting in the background.
2762  std::vector<Color> colors = {Color{0.9568, 0.2627, 0.2118, 1.0},
2763  Color{0.1294, 0.5882, 0.9529, 1.0}};
2764  std::vector<Scalar> stops = {
2765  0.0,
2766  1.0,
2767  };
2768  paint.color_source = ColorSource::MakeLinearGradient(
2769  {0, 0}, {100, 100}, std::move(colors), std::move(stops),
2770  Entity::TileMode::kRepeat, {});
2771  canvas.DrawPaint(paint);
2772 
2773  Rect clip_rect = Rect::MakeLTRB(50, 50, 400, 300);
2774 
2775  // Draw a clipped SaveLayer, where the clip coverage and SaveLayer size are
2776  // the same.
2777  canvas.ClipRRect(clip_rect, Size(100, 100),
2778  Entity::ClipOperation::kIntersect);
2779  canvas.SaveLayer({}, clip_rect,
2780  ImageFilter::MakeFromColorFilter(*ColorFilter::MakeBlend(
2781  BlendMode::kExclusion, Color::Red())));
2782  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2783 }

References impeller::Canvas::ClipRRect(), impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), impeller::kExclusion, impeller::Entity::kIntersect, impeller::Entity::kRepeat, impeller::ColorFilter::MakeBlend(), impeller::ImageFilter::MakeFromColorFilter(), impeller::ColorSource::MakeLinearGradient(), impeller::TRect< Scalar >::MakeLTRB(), paint, impeller::Color::Red(), impeller::Canvas::SaveLayer(), and impeller::Canvas::Scale().

◆ TEST_P() [29/456]

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

Definition at line 130 of file aiks_blur_unittests.cc.

130  {
131  Canvas canvas;
132  canvas.ClipRect(Rect::MakeXYWH(100, 150, 400, 400));
133  canvas.DrawCircle(
134  {400, 400}, 200,
135  {
136  .color = Color::Green(),
137  .image_filter = ImageFilter::MakeBlur(
138  Sigma(20.0), Sigma(20.0), FilterContents::BlurStyle::kNormal,
139  Entity::TileMode::kDecal),
140  });
141  canvas.Restore();
142 
143  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
144 }

References impeller::Canvas::ClipRect(), impeller::Canvas::DrawCircle(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::Green(), impeller::Entity::kDecal, impeller::FilterContents::kNormal, impeller::ImageFilter::MakeBlur(), impeller::TRect< Scalar >::MakeXYWH(), and impeller::Canvas::Restore().

◆ TEST_P() [30/456]

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

Definition at line 1469 of file aiks_unittests.cc.

1469  {
1470  Canvas canvas;
1471 
1472  canvas.DrawPaint({.color = Color::White()});
1473 
1474  // Draw a green circle on the screen.
1475  {
1476  // Increase the clip depth for the savelayer to contend with.
1477  canvas.ClipPath(PathBuilder{}.AddCircle({100, 100}, 50).TakePath());
1478 
1479  canvas.SaveLayer({}, Rect::MakeXYWH(50, 50, 100, 100));
1480 
1481  // Fill the layer with white.
1482  canvas.DrawRect(Rect::MakeSize(Size{400, 400}), {.color = Color::White()});
1483  // Fill the layer with green, but do so with a color blend that can't be
1484  // collapsed into the parent pass.
1485  // TODO(jonahwilliams): this blend mode was changed from color burn to
1486  // hardlight to work around https://github.com/flutter/flutter/issues/136554
1487  // .
1488  canvas.DrawRect(
1489  Rect::MakeSize(Size{400, 400}),
1490  {.color = Color::Green(), .blend_mode = BlendMode::kHardLight});
1491  }
1492 
1493  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1494 }

References impeller::PathBuilder::AddCircle(), impeller::Canvas::ClipPath(), impeller::Canvas::DrawPaint(), impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::Green(), impeller::kHardLight, impeller::TRect< Scalar >::MakeSize(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Canvas::SaveLayer(), and impeller::Color::White().

◆ TEST_P() [31/456]

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

Definition at line 2181 of file aiks_unittests.cc.

2181  {
2182  auto runtime_stages =
2183  OpenAssetAsRuntimeStage("runtime_stage_example.frag.iplr");
2184 
2185  auto runtime_stage =
2186  runtime_stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
2187  ASSERT_TRUE(runtime_stage);
2188  ASSERT_TRUE(runtime_stage->IsDirty());
2189 
2190  struct FragUniforms {
2191  Vector2 iResolution;
2192  Scalar iTime;
2193  } frag_uniforms = {.iResolution = Vector2(400, 400), .iTime = 100.0};
2194  auto uniform_data = std::make_shared<std::vector<uint8_t>>();
2195  uniform_data->resize(sizeof(FragUniforms));
2196  memcpy(uniform_data->data(), &frag_uniforms, sizeof(FragUniforms));
2197 
2198  std::vector<RuntimeEffectContents::TextureInput> texture_inputs;
2199 
2200  Paint paint;
2201  paint.color_source = ColorSource::MakeRuntimeEffect(
2202  runtime_stage, uniform_data, texture_inputs);
2203 
2204  Canvas canvas;
2205  canvas.Save();
2206  canvas.ClipRRect(Rect::MakeXYWH(0, 0, 400, 400), {10.0, 10.0},
2207  Entity::ClipOperation::kIntersect);
2208  canvas.DrawRect(Rect::MakeXYWH(0, 0, 400, 400), paint);
2209  canvas.Restore();
2210 
2211  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2212 }

References impeller::Canvas::ClipRRect(), impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::Entity::kIntersect, impeller::ColorSource::MakeRuntimeEffect(), impeller::TRect< Scalar >::MakeXYWH(), paint, impeller::PlaygroundBackendToRuntimeStageBackend(), impeller::Canvas::Restore(), and impeller::Canvas::Save().

◆ TEST_P() [32/456]

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

Definition at line 397 of file aiks_path_unittests.cc.

397  {
398  Canvas canvas;
399  Paint paint;
400  paint.color = Color::Fuchsia();
401  canvas.ClipPath(
402  PathBuilder{}.AddRect(Rect::MakeXYWH(0, 0, 500, 500)).TakePath());
403  canvas.DrawPath(PathBuilder{}.AddCircle({500, 500}, 250).TakePath(), paint);
404  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
405 }

References impeller::PathBuilder::AddCircle(), impeller::PathBuilder::AddRect(), impeller::Canvas::ClipPath(), impeller::Canvas::DrawPath(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::Fuchsia(), impeller::TRect< Scalar >::MakeXYWH(), and paint.

◆ TEST_P() [33/456]

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

Definition at line 73 of file aiks_unittests.cc.

73  {
74  Canvas canvas;
75  Paint paint;
76  paint.color = Color::Blue();
77  canvas.DrawPath(PathBuilder{}
78  .AddRect(Rect::MakeXYWH(100.0, 100.0, 100.0, 100.0))
79  .TakePath(),
80  paint);
81  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
82 }

References impeller::PathBuilder::AddRect(), impeller::Color::Blue(), impeller::Canvas::DrawPath(), impeller::Canvas::EndRecordingAsPicture(), impeller::TRect< Scalar >::MakeXYWH(), and paint.

◆ TEST_P() [34/456]

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

Definition at line 106 of file aiks_unittests.cc.

106  {
107  Canvas canvas;
108  Paint paint;
109  paint.color = Color::Red();
110  paint.color_filter =
111  ColorFilter::MakeBlend(BlendMode::kSourceOver, Color::Yellow());
112  paint.invert_colors = true;
113 
114  canvas.DrawRect(Rect::MakeLTRB(0, 0, 100, 100), paint);
115  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
116 }

References impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::kSourceOver, impeller::ColorFilter::MakeBlend(), impeller::TRect< Scalar >::MakeLTRB(), paint, impeller::Color::Red(), and impeller::Color::Yellow().

◆ TEST_P() [35/456]

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

Definition at line 118 of file aiks_unittests.cc.

118  {
119  Canvas canvas;
120  Paint paint;
121  paint.color = Color::Red();
122  paint.color_filter =
123  ColorFilter::MakeBlend(BlendMode::kSourceOver, Color::Yellow());
124  paint.invert_colors = true;
125 
126  canvas.DrawPaint(paint);
127  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
128 }

References impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), impeller::kSourceOver, impeller::ColorFilter::MakeBlend(), paint, impeller::Color::Red(), and impeller::Color::Yellow().

◆ TEST_P() [36/456]

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

Definition at line 550 of file aiks_dl_gradient_unittests.cc.

550  {
551  Scalar size = 256;
552  DisplayListBuilder builder;
553  DlPaint paint;
554  paint.setColor(DlColor::kWhite());
555  builder.DrawRect(SkRect::MakeXYWH(0, 0, size * 3, size * 3), paint);
556  std::vector<DlColor> colors = {
557  DlColor(Color::MakeRGBA8(0xF4, 0x43, 0x36, 0xFF).ToARGB()),
558  DlColor(Color::MakeRGBA8(0xFF, 0xEB, 0x3B, 0xFF).ToARGB()),
559  DlColor(Color::MakeRGBA8(0x4c, 0xAF, 0x50, 0xFF).ToARGB()),
560  DlColor(Color::MakeRGBA8(0x21, 0x96, 0xF3, 0xFF).ToARGB())};
561  std::vector<Scalar> stops = {0.0, 1.f / 3.f, 2.f / 3.f, 1.0};
562  std::array<std::tuple<SkPoint, float, SkPoint, float>, 8> array{
563  std::make_tuple(SkPoint::Make(size / 2.f, size / 2.f), 0.f,
564  SkPoint::Make(size / 2.f, size / 2.f), size / 2.f),
565  std::make_tuple(SkPoint::Make(size / 2.f, size / 2.f), size / 4.f,
566  SkPoint::Make(size / 2.f, size / 2.f), size / 2.f),
567  std::make_tuple(SkPoint::Make(size / 4.f, size / 4.f), 0.f,
568  SkPoint::Make(size / 2.f, size / 2.f), size / 2.f),
569  std::make_tuple(SkPoint::Make(size / 4.f, size / 4.f), size / 2.f,
570  SkPoint::Make(size / 2.f, size / 2.f), 0),
571  std::make_tuple(SkPoint::Make(size / 4.f, size / 4.f), size / 4.f,
572  SkPoint::Make(size / 2.f, size / 2.f), size / 2.f),
573  std::make_tuple(SkPoint::Make(size / 4.f, size / 4.f), size / 16.f,
574  SkPoint::Make(size / 2.f, size / 2.f), size / 8.f),
575  std::make_tuple(SkPoint::Make(size / 4.f, size / 4.f), size / 8.f,
576  SkPoint::Make(size / 2.f, size / 2.f), size / 16.f),
577  std::make_tuple(SkPoint::Make(size / 8.f, size / 8.f), size / 8.f,
578  SkPoint::Make(size / 2.f, size / 2.f), size / 8.f),
579  };
580  for (int i = 0; i < 8; i++) {
581  builder.Save();
582  builder.Translate((i % 3) * size, i / 3 * size);
583  paint.setColorSource(DlColorSource::MakeConical(
584  std::get<2>(array[i]), std::get<3>(array[i]), std::get<0>(array[i]),
585  std::get<1>(array[i]), stops.size(), colors.data(), stops.data(),
586  DlTileMode::kClamp));
587  builder.DrawRect(SkRect::MakeXYWH(0, 0, size, size), paint);
588  builder.Restore();
589  }
590  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
591 }

References paint.

◆ TEST_P() [37/456]

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

Definition at line 186 of file aiks_dl_gradient_unittests.cc.

186  {
188 }

References CanRenderConicalGradientWithDithering().

◆ TEST_P() [38/456]

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

Definition at line 31 of file aiks_path_unittests.cc.

31  {
32  Canvas canvas;
33  Paint paint;
34  paint.color = Color::Red();
35  paint.stroke_width = 25.0;
36  paint.style = Paint::Style::kStroke;
37  canvas.DrawPath(PathBuilder{}.AddCircle({500, 500}, 250).TakePath(), paint);
38  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
39 }

References impeller::PathBuilder::AddCircle(), impeller::Canvas::DrawPath(), impeller::Canvas::EndRecordingAsPicture(), impeller::Paint::kStroke, paint, and impeller::Color::Red().

◆ TEST_P() [39/456]

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

Definition at line 2166 of file aiks_unittests.cc.

2166  {
2167  Canvas canvas;
2168 
2169  canvas.DrawPaint({.color = Color::Red()});
2170  // Draw an empty savelayer with a destructive blend mode, which will replace
2171  // the entire red screen with fully transparent black, except for the green
2172  // circle drawn within the layer.
2173  canvas.SaveLayer({.blend_mode = BlendMode::kSource});
2174  canvas.DrawCircle({300, 300}, 100, {.color = Color::Green()});
2175  canvas.Restore();
2176 
2177  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2178 }

References impeller::Canvas::DrawCircle(), impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::Green(), impeller::kSource, impeller::Color::Red(), impeller::Canvas::Restore(), and impeller::Canvas::SaveLayer().

◆ TEST_P() [40/456]

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

Definition at line 42 of file aiks_dl_clip_unittests.cc.

42  {
43  DisplayListBuilder builder;
44  builder.Translate(400, 400);
45 
46  // Limit drawing to face circle with a clip.
47  builder.ClipPath(CreateCircle(0, 0, 200));
48  builder.Save();
49 
50  // Cut away eyes/mouth using difference clips.
51  builder.ClipPath(CreateCircle(-100, -50, 30), DlCanvas::ClipOp::kDifference);
52  builder.ClipPath(CreateCircle(100, -50, 30), DlCanvas::ClipOp::kDifference);
53 
54  SkPath path;
55  path.moveTo(-100, 50);
56  path.quadTo(0, 150, 100, 50);
57  builder.ClipPath(path, DlCanvas::ClipOp::kDifference);
58 
59  // Draw a huge yellow rectangle to prove the clipping works.
60  DlPaint paint;
61  paint.setColor(DlColor::kYellow());
62  builder.DrawRect(SkRect::MakeXYWH(-1000, -1000, 2000, 2000), paint);
63 
64  // Remove the difference clips and draw hair that partially covers the eyes.
65  builder.Restore();
66  paint.setColor(DlColor::kMaroon());
67  SkPath path_2;
68  path_2.moveTo(200, -200);
69  path_2.lineTo(-200, -200);
70  path_2.lineTo(-200, -40);
71  path_2.cubicTo({0, -40}, {0, -80}, {200, -80});
72 
73  builder.DrawPath(path_2, paint);
74 
75  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
76 }

References paint.

◆ TEST_P() [41/456]

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

Definition at line 113 of file aiks_path_unittests.cc.

113  {
114  Canvas canvas;
115 
116  Paint paint;
117  paint.color = Color::Red();
118 
119  PathBuilder builder;
120 
121  PathBuilder::RoundingRadii radii;
122  radii.top_left = {50, 25};
123  radii.top_right = {25, 50};
124  radii.bottom_right = {50, 25};
125  radii.bottom_left = {25, 50};
126 
127  builder.AddRoundedRect(Rect::MakeXYWH(100, 100, 200, 200), radii);
128  builder.AddCircle({200, 200}, 50);
129  auto path = builder.TakePath(FillType::kOdd);
130 
131  canvas.DrawImage(
132  std::make_shared<Image>(CreateTextureForFixture("boston.jpg")), {10, 10},
133  Paint{});
134  canvas.DrawPath(path, paint);
135 
136  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
137 }

References impeller::PathBuilder::AddCircle(), impeller::PathBuilder::AddRoundedRect(), impeller::PathBuilder::RoundingRadii::bottom_left, impeller::PathBuilder::RoundingRadii::bottom_right, impeller::Canvas::DrawImage(), impeller::Canvas::DrawPath(), impeller::Canvas::EndRecordingAsPicture(), impeller::kOdd, impeller::TRect< Scalar >::MakeXYWH(), paint, impeller::Color::Red(), impeller::PathBuilder::TakePath(), impeller::PathBuilder::RoundingRadii::top_left, and impeller::PathBuilder::RoundingRadii::top_right.

◆ TEST_P() [42/456]

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

Definition at line 332 of file aiks_unittests.cc.

332  {
333  Canvas canvas;
334  Paint paint;
335 
336  std::vector<Color> colors = {Color{0.9568, 0.2627, 0.2118, 1.0},
337  Color{0.1294, 0.5882, 0.9529, 1.0}};
338  std::vector<Scalar> stops = {
339  0.0,
340  1.0,
341  };
342 
343  paint.color_source = ColorSource::MakeLinearGradient(
344  {0, 0}, {100, 100}, std::move(colors), std::move(stops),
345  Entity::TileMode::kRepeat, {});
346 
347  canvas.Save();
348  canvas.Translate({100, 100, 0});
349  canvas.DrawRect(Rect::MakeXYWH(0, 0, 200, 200), paint);
350  canvas.Restore();
351 
352  canvas.Save();
353  canvas.Translate({100, 400, 0});
354  canvas.DrawCircle({100, 100}, 100, paint);
355  canvas.Restore();
356  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
357 }

References impeller::Canvas::DrawCircle(), impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::Entity::kRepeat, impeller::ColorSource::MakeLinearGradient(), impeller::TRect< Scalar >::MakeXYWH(), paint, impeller::Canvas::Restore(), impeller::Canvas::Save(), and impeller::Canvas::Translate().

◆ TEST_P() [43/456]

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

Definition at line 747 of file aiks_unittests.cc.

747  {
748  Canvas canvas;
749  canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)});
750 
751  ASSERT_TRUE(RenderTextInCanvasSkia(
752  GetContext(), canvas, "😀 😃 😄 😁 😆 😅 😂 🤣 🥲 😊", kFontFixture));
753  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
754 }

References impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), kFontFixture, and RenderTextInCanvasSkia().

◆ TEST_P() [44/456]

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

Definition at line 769 of file aiks_unittests.cc.

769  {
770  Canvas canvas;
771  canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)});
772 
773  ASSERT_TRUE(RenderTextInCanvasSkia(
774  GetContext(), canvas, "😀 😃 😄 😁 😆 😅 😂 🤣 🥲 😊", kFontFixture,
775  {.color = Color::Black().WithAlpha(0.5)}));
776  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
777 }

References impeller::Color::Black(), impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), kFontFixture, RenderTextInCanvasSkia(), and impeller::Color::WithAlpha().

◆ TEST_P() [45/456]

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

Definition at line 756 of file aiks_unittests.cc.

756  {
757  Canvas canvas;
758  canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)});
759 
760  ASSERT_TRUE(RenderTextInCanvasSkia(
761  GetContext(), canvas, "😀 😃 😄 😁 😆 😅 😂 🤣 🥲 😊", kFontFixture,
762  TextRenderOptions{.color = Color::Blue(),
763  .mask_blur_descriptor = Paint::MaskBlurDescriptor{
764  .style = FilterContents::BlurStyle::kNormal,
765  .sigma = Sigma(4)}}));
766  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
767 }

References impeller::Color::Blue(), impeller::testing::TextRenderOptions::color, impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), kFontFixture, impeller::FilterContents::kNormal, RenderTextInCanvasSkia(), and impeller::Paint::MaskBlurDescriptor::style.

◆ TEST_P() [46/456]

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

Definition at line 57 of file aiks_blur_unittests.cc.

57  {
58  // This case triggers the ForegroundAdvancedBlend path. The color filter
59  // should apply to the color only, and respect the alpha mask.
60  Canvas canvas;
61  canvas.ClipRect(Rect::MakeXYWH(100, 150, 400, 400));
62  canvas.DrawCircle({400, 400}, 200,
63  {
64  .color = Color::Grey(),
65  .color_filter = ColorFilter::MakeBlend(
66  BlendMode::kColor, Color::Green()),
67  .mask_blur_descriptor =
68  Paint::MaskBlurDescriptor{
69  .style = FilterContents::BlurStyle::kNormal,
70  .sigma = Radius(20),
71  },
72  });
73  canvas.Restore();
74 
75  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
76 }

References impeller::Canvas::ClipRect(), impeller::Canvas::DrawCircle(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::Green(), impeller::Color::Grey(), impeller::kColor, impeller::FilterContents::kNormal, impeller::ColorFilter::MakeBlend(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Canvas::Restore(), and impeller::Paint::MaskBlurDescriptor::style.

◆ TEST_P() [47/456]

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

Definition at line 36 of file aiks_blur_unittests.cc.

36  {
37  // This case triggers the ForegroundPorterDuffBlend path. The color filter
38  // should apply to the color only, and respect the alpha mask.
39  Canvas canvas;
40  canvas.ClipRect(Rect::MakeXYWH(100, 150, 400, 400));
41  canvas.DrawCircle({400, 400}, 200,
42  {
43  .color = Color::White(),
44  .color_filter = ColorFilter::MakeBlend(
45  BlendMode::kSource, Color::Green()),
46  .mask_blur_descriptor =
47  Paint::MaskBlurDescriptor{
48  .style = FilterContents::BlurStyle::kNormal,
49  .sigma = Radius(20),
50  },
51  });
52  canvas.Restore();
53 
54  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
55 }

References impeller::Canvas::ClipRect(), impeller::Canvas::DrawCircle(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::Green(), impeller::FilterContents::kNormal, impeller::kSource, impeller::ColorFilter::MakeBlend(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Canvas::Restore(), impeller::Paint::MaskBlurDescriptor::style, and impeller::Color::White().

◆ TEST_P() [48/456]

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

Definition at line 593 of file aiks_dl_gradient_unittests.cc.

593  {
594  std::vector<DlColor> colors = {
595  DlColor(Color::MakeRGBA8(0xF4, 0x43, 0x36, 0xFF).ToARGB()),
596  DlColor(Color::MakeRGBA8(0xFF, 0xEB, 0x3B, 0xFF).ToARGB()),
597  DlColor(Color::MakeRGBA8(0x4c, 0xAF, 0x50, 0xFF).ToARGB()),
598  DlColor(Color::MakeRGBA8(0x21, 0x96, 0xF3, 0xFF).ToARGB())};
599  std::vector<Scalar> stops = {0.0, 1.f / 3.f, 2.f / 3.f, 1.0};
600 
601  std::array<std::shared_ptr<DlColorSource>, 3> color_sources = {
602  DlColorSource::MakeLinear({0, 0}, {100, 100}, stops.size(), colors.data(),
603  stops.data(), DlTileMode::kDecal),
604  DlColorSource::MakeRadial({100, 100}, 100, stops.size(), colors.data(),
605  stops.data(), DlTileMode::kDecal),
606  DlColorSource::MakeSweep({100, 100}, 45, 135, stops.size(), colors.data(),
607  stops.data(), DlTileMode::kDecal),
608  };
609 
610  DisplayListBuilder builder;
611  DlPaint paint;
612  paint.setColor(DlColor::kWhite());
613  builder.DrawRect(SkRect::MakeLTRB(0, 0, 605, 205), paint);
614  for (int i = 0; i < 3; i++) {
615  builder.Save();
616  builder.Translate(i * 200.0f, 0);
617  paint.setColorSource(color_sources[i]);
618  builder.DrawRect(SkRect::MakeLTRB(0, 0, 200, 200), paint);
619  builder.Restore();
620  }
621  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
622 }

References paint.

◆ TEST_P() [49/456]

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

Definition at line 35 of file aiks_dl_opacity_unittests.cc.

35  {
36  DisplayListBuilder builder;
37 
38  DlPaint red;
39  red.setColor(DlColor::kRed());
40  DlPaint green;
41  green.setColor(DlColor::kGreen().modulateOpacity(0.5));
42  DlPaint blue;
43  blue.setColor(DlColor::kBlue());
44 
45  DlPaint alpha;
46  alpha.setColor(DlColor::kRed().modulateOpacity(0.5));
47 
48  builder.SaveLayer(nullptr, &alpha);
49  builder.DrawRect(SkRect::MakeXYWH(0, 0, 100, 100), red);
50  builder.DrawRect(SkRect::MakeXYWH(200, 200, 100, 100), green);
51  builder.DrawRect(SkRect::MakeXYWH(400, 400, 100, 100), blue);
52  builder.Restore();
53 
54  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
55 }

◆ TEST_P() [50/456]

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

Definition at line 57 of file aiks_dl_opacity_unittests.cc.

57  {
58  DisplayListBuilder builder;
59 
60  DlPaint red;
61  red.setColor(DlColor::kRed());
62 
63  DlPaint alpha;
64  alpha.setColor(DlColor::kRed().modulateOpacity(0.7));
65 
66  // Create a saveLayer that will forward its opacity to another
67  // saveLayer, to verify that we correctly distribute opacity.
68  SkRect bounds = SkRect::MakeLTRB(0, 0, 500, 500);
69  builder.SaveLayer(&bounds, &alpha);
70  builder.SaveLayer(&bounds, &alpha);
71  builder.DrawRect(SkRect::MakeXYWH(0, 0, 400, 400), red);
72  builder.DrawRect(SkRect::MakeXYWH(0, 0, 450, 450), red);
73  builder.Restore();
74  builder.Restore();
75 
76  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
77 }

◆ TEST_P() [51/456]

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

Definition at line 84 of file aiks_unittests.cc.

84  {
85  Canvas canvas;
86  Paint paint;
87  auto image = std::make_shared<Image>(CreateTextureForFixture("kalimba.jpg"));
88  paint.color = Color::Red();
89  canvas.DrawImage(image, Point::MakeXY(100.0, 100.0), paint);
90  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
91 }

References impeller::Canvas::DrawImage(), impeller::Canvas::EndRecordingAsPicture(), impeller::TPoint< Scalar >::MakeXY(), paint, and impeller::Color::Red().

◆ TEST_P() [52/456]

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

Definition at line 219 of file aiks_unittests.cc.

219  {
220  Canvas canvas;
221  Paint paint;
222  auto image = std::make_shared<Image>(CreateTextureForFixture("kalimba.jpg"));
223  Size image_half_size = Size(image->GetSize()) * 0.5;
224 
225  // Render the bottom right quarter of the source image in a stretched rect.
226  auto source_rect = Rect::MakeSize(image_half_size);
227  source_rect = source_rect.Shift(Point(image_half_size));
228 
229  canvas.DrawImageRect(image, source_rect, Rect::MakeXYWH(100, 100, 600, 600),
230  paint);
231  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
232 }

References impeller::Canvas::DrawImageRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::TRect< Scalar >::MakeSize(), impeller::TRect< Scalar >::MakeXYWH(), and paint.

◆ TEST_P() [53/456]

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

Definition at line 93 of file aiks_unittests.cc.

93  {
94  Canvas canvas;
95  Paint paint;
96  auto image = std::make_shared<Image>(CreateTextureForFixture("kalimba.jpg"));
97  paint.color = Color::Red();
98  paint.color_filter =
99  ColorFilter::MakeBlend(BlendMode::kSourceOver, Color::Yellow());
100  paint.invert_colors = true;
101 
102  canvas.DrawImage(image, Point::MakeXY(100.0, 100.0), paint);
103  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
104 }

References impeller::Canvas::DrawImage(), impeller::Canvas::EndRecordingAsPicture(), impeller::kSourceOver, impeller::ColorFilter::MakeBlend(), impeller::TPoint< Scalar >::MakeXY(), paint, impeller::Color::Red(), and impeller::Color::Yellow().

◆ TEST_P() [54/456]

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

Definition at line 730 of file aiks_unittests.cc.

730  {
731  Canvas canvas;
732  canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)});
733 
734  ASSERT_TRUE(RenderTextInCanvasSkia(
735  GetContext(), canvas, "the quick brown fox jumped over the lazy dog!.?",
736  "HomemadeApple.ttf"));
737  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
738 }

References impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), and RenderTextInCanvasSkia().

◆ TEST_P() [55/456]

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

Definition at line 67 of file aiks_dl_gradient_unittests.cc.

67  {
68  CanRenderLinearGradient(this, DlTileMode::kClamp);
69 }

◆ TEST_P() [56/456]

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

Definition at line 76 of file aiks_dl_gradient_unittests.cc.

76  {
77  CanRenderLinearGradient(this, DlTileMode::kDecal);
78 }

◆ TEST_P() [57/456]

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

Definition at line 80 of file aiks_dl_gradient_unittests.cc.

80  {
81  DisplayListBuilder builder;
82  Point scale = GetContentScale();
83  builder.Scale(scale.x, scale.y);
84  DlPaint paint;
85  builder.Translate(100.0f, 0);
86 
87  std::vector<DlColor> colors = {
88  DlColor(Color{0.9568, 0.2627, 0.2118, 1.0}.ToARGB()),
89  DlColor(Color{0.1294, 0.5882, 0.9529, 0.0}.ToARGB())};
90  std::vector<Scalar> stops = {0.0, 1.0};
91 
92  paint.setColorSource(DlColorSource::MakeLinear(
93  {0, 0}, {200, 200}, 2, colors.data(), stops.data(), DlTileMode::kDecal));
94  // Overlay the gradient with 25% green. This should appear as the entire
95  // rectangle being drawn with 25% green, including the border area outside the
96  // decal gradient.
97  paint.setColorFilter(DlBlendColorFilter::Make(DlColor::kGreen().withAlpha(64),
98  DlBlendMode::kSrcOver));
99  paint.setColor(DlColor::kWhite());
100  builder.DrawRect(SkRect::MakeXYWH(0, 0, 600, 600), paint);
101  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
102 }

References paint, scale, and impeller::Color::ToARGB().

◆ TEST_P() [58/456]

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

Definition at line 256 of file aiks_dl_gradient_unittests.cc.

256  {
257  CanRenderLinearGradientManyColors(this, DlTileMode::kClamp);
258 }

◆ TEST_P() [59/456]

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

Definition at line 265 of file aiks_dl_gradient_unittests.cc.

265  {
266  CanRenderLinearGradientManyColors(this, DlTileMode::kDecal);
267 }

◆ TEST_P() [60/456]

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

Definition at line 262 of file aiks_dl_gradient_unittests.cc.

262  {
263  CanRenderLinearGradientManyColors(this, DlTileMode::kMirror);
264 }

◆ TEST_P() [61/456]

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

Definition at line 259 of file aiks_dl_gradient_unittests.cc.

259  {
260  CanRenderLinearGradientManyColors(this, DlTileMode::kRepeat);
261 }

◆ TEST_P() [62/456]

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

Definition at line 300 of file aiks_dl_gradient_unittests.cc.

300  {
301  auto callback = [&]() -> sk_sp<DisplayList> {
302  const char* tile_mode_names[] = {"Clamp", "Repeat", "Mirror", "Decal"};
303  const DlTileMode tile_modes[] = {DlTileMode::kClamp, DlTileMode::kRepeat,
304  DlTileMode::kMirror, DlTileMode::kDecal};
305 
306  static int selected_tile_mode = 0;
307  static Matrix matrix;
308  if (AiksTest::ImGuiBegin("Controls", nullptr,
309  ImGuiWindowFlags_AlwaysAutoResize)) {
310  ImGui::Combo("Tile mode", &selected_tile_mode, tile_mode_names,
311  sizeof(tile_mode_names) / sizeof(char*));
312  std::string label = "##1";
313  for (int i = 0; i < 4; i++) {
314  ImGui::InputScalarN(label.c_str(), ImGuiDataType_Float,
315  &(matrix.vec[i]), 4, NULL, NULL, "%.2f", 0);
316  label[2]++;
317  }
318  ImGui::End();
319  }
320 
321  DisplayListBuilder builder;
322  DlPaint paint;
323  builder.Translate(100.0, 100.0);
324  auto tile_mode = tile_modes[selected_tile_mode];
325 
326  std::vector<DlColor> colors = {
327  DlColor(Color{0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0}.ToARGB()),
328  DlColor(Color{0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0}.ToARGB()),
329  DlColor(Color{0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0}.ToARGB()),
330  DlColor(Color{0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0}.ToARGB()),
331  DlColor(Color{0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0}.ToARGB()),
332  DlColor(Color{0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0}.ToARGB()),
333  DlColor(Color{0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0}.ToARGB())};
334  std::vector<Scalar> stops = {
335  0.0, 2.0 / 62.0, 4.0 / 62.0, 8.0 / 62.0, 16.0 / 62.0, 32.0 / 62.0, 1.0,
336  };
337 
338  paint.setColorSource(DlColorSource::MakeLinear({0, 0}, {200, 200},
339  stops.size(), colors.data(),
340  stops.data(), tile_mode));
341 
342  builder.DrawRect(SkRect::MakeXYWH(0, 0, 600, 600), paint);
343  return builder.Build();
344  };
345  ASSERT_TRUE(OpenPlaygroundHere(callback));
346 }

References paint, impeller::Color::ToARGB(), and impeller::Matrix::vec.

◆ TEST_P() [63/456]

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

Definition at line 348 of file aiks_dl_gradient_unittests.cc.

348  {
349  DisplayListBuilder builder;
350 
351  std::vector<DlColor> colors = {
352  DlColor::kRed(), DlColor::kWhite(), DlColor::kRed(), DlColor::kWhite(),
353  DlColor::kRed(), DlColor::kWhite(), DlColor::kRed(), DlColor::kWhite(),
354  DlColor::kRed(), DlColor::kWhite(), DlColor::kRed()};
355  std::vector<Scalar> stops = {0.0, 0.1, 0.2, 0.3, 0.4, 0.5,
356  0.6, 0.7, 0.8, 0.9, 1.0};
357 
358  DlPaint paint;
359  paint.setColor(DlColor::kWhite());
360  paint.setColorSource(DlColorSource::MakeLinear(
361  {200, 200}, {400, 400}, stops.size(), colors.data(), stops.data(),
362  DlTileMode::kClamp));
363  paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kNormal, 20));
364 
365  builder.DrawCircle({300, 300}, 200, paint);
366  builder.DrawRect(SkRect::MakeLTRB(100, 300, 500, 600), paint);
367 
368  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
369 }

References paint.

◆ TEST_P() [64/456]

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

Definition at line 73 of file aiks_dl_gradient_unittests.cc.

73  {
74  CanRenderLinearGradient(this, DlTileMode::kMirror);
75 }

◆ TEST_P() [65/456]

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

Definition at line 70 of file aiks_dl_gradient_unittests.cc.

70  {
71  CanRenderLinearGradient(this, DlTileMode::kRepeat);
72 }

◆ TEST_P() [66/456]

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

Definition at line 296 of file aiks_dl_gradient_unittests.cc.

296  {
297  CanRenderLinearGradientWayManyColors(this, DlTileMode::kClamp);
298 }

◆ TEST_P() [67/456]

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

Definition at line 120 of file aiks_dl_gradient_unittests.cc.

120  {
122 }

References CanRenderLinearGradientWithDithering().

◆ TEST_P() [68/456]

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

Definition at line 215 of file aiks_dl_gradient_unittests.cc.

215  {
216  CanRenderLinearGradientWithOverlappingStops(this, DlTileMode::kClamp);
217 }

◆ TEST_P() [69/456]

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

Definition at line 23 of file aiks_blur_unittests.cc.

23  {
24  Canvas canvas;
25  canvas.DrawCircle({400, 400}, 300,
26  {.color = Color::Green(),
27  .mask_blur_descriptor = Paint::MaskBlurDescriptor{
28  .style = FilterContents::BlurStyle::kNormal,
29  .sigma = Sigma(99999),
30  }});
31  canvas.Restore();
32 
33  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
34 }

References impeller::Canvas::DrawCircle(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::Green(), impeller::FilterContents::kNormal, impeller::Canvas::Restore(), and impeller::Paint::MaskBlurDescriptor::style.

◆ TEST_P() [70/456]

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

Definition at line 27 of file aiks_dl_clip_unittests.cc.

27  {
28  DisplayListBuilder builder;
29  DlPaint paint;
30  paint.setColor(DlColor::kFuchsia());
31 
32  builder.Save();
33  builder.ClipPath(CreateCircle(200, 400, 300));
34  builder.Restore();
35  builder.ClipPath(CreateCircle(600, 400, 300));
36  builder.ClipPath(CreateCircle(400, 600, 300));
37  builder.DrawRect(SkRect::MakeXYWH(200, 200, 400, 400), paint);
38 
39  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
40 }

References paint.

◆ TEST_P() [71/456]

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

Definition at line 407 of file aiks_path_unittests.cc.

407  {
408  Canvas canvas;
409 
410  Paint paint;
411  paint.color = Color::Red();
412 
413  PathBuilder::RoundingRadii radii;
414  radii.top_left = {50, 50};
415  radii.top_right = {50, 50};
416  radii.bottom_right = {50, 50};
417  radii.bottom_left = {50, 50};
418 
419  const Scalar kTriangleHeight = 100;
420  canvas.Translate(Vector2(200, 200));
421  // Form a path similar to the Material drop slider value indicator. Both
422  // shapes should render identically side-by-side.
423  {
424  auto path =
425  PathBuilder{}
426  .MoveTo({0, kTriangleHeight})
427  .LineTo({-kTriangleHeight / 2.0f, 0})
428  .LineTo({kTriangleHeight / 2.0f, 0})
429  .Close()
430  .AddRoundedRect(
431  Rect::MakeXYWH(-kTriangleHeight / 2.0f, -kTriangleHeight / 2.0f,
432  kTriangleHeight, kTriangleHeight),
433  radii)
434  .TakePath();
435 
436  canvas.DrawPath(path, paint);
437  }
438  canvas.Translate(Vector2(100, 0));
439  {
440  auto path =
441  PathBuilder{}
442  .MoveTo({0, kTriangleHeight})
443  .LineTo({-kTriangleHeight / 2.0f, 0})
444  .LineTo({0, -10})
445  .LineTo({kTriangleHeight / 2.0f, 0})
446  .Close()
447  .AddRoundedRect(
448  Rect::MakeXYWH(-kTriangleHeight / 2.0f, -kTriangleHeight / 2.0f,
449  kTriangleHeight, kTriangleHeight),
450  radii)
451  .TakePath();
452 
453  canvas.DrawPath(path, paint);
454  }
455 
456  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
457 }

References impeller::PathBuilder::RoundingRadii::bottom_left, impeller::PathBuilder::RoundingRadii::bottom_right, impeller::Close(), impeller::Canvas::DrawPath(), impeller::Canvas::EndRecordingAsPicture(), impeller::LineTo(), impeller::TRect< Scalar >::MakeXYWH(), impeller::PathBuilder::MoveTo(), paint, impeller::Color::Red(), impeller::PathBuilder::RoundingRadii::top_left, impeller::PathBuilder::RoundingRadii::top_right, and impeller::Canvas::Translate().

◆ TEST_P() [72/456]

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

Definition at line 94 of file aiks_path_unittests.cc.

94  {
95  Canvas canvas;
96 
97  Paint paint;
98  paint.color = Color::Red();
99  paint.style = Paint::Style::kStroke;
100  paint.stroke_cap = Cap::kRound;
101  paint.stroke_width = 50;
102 
103  // Should draw a diagonal pill shape. If flat on either end, the stroke is
104  // rendering wrong.
105  PathBuilder builder;
106  builder.MoveTo({250, 250});
107  builder.QuadraticCurveTo({100, 100}, {250, 250});
108 
109  canvas.DrawPath(builder.TakePath(), paint);
110  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
111 }

References impeller::Canvas::DrawPath(), impeller::Canvas::EndRecordingAsPicture(), impeller::kRound, impeller::Paint::kStroke, impeller::PathBuilder::MoveTo(), paint, impeller::PathBuilder::QuadraticCurveTo(), impeller::Color::Red(), and impeller::PathBuilder::TakePath().

◆ TEST_P() [73/456]

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

Definition at line 371 of file aiks_dl_gradient_unittests.cc.

371  {
372  auto callback = [&]() -> sk_sp<DisplayList> {
373  const char* tile_mode_names[] = {"Clamp", "Repeat", "Mirror", "Decal"};
374  const DlTileMode tile_modes[] = {DlTileMode::kClamp, DlTileMode::kRepeat,
375  DlTileMode::kMirror, DlTileMode::kDecal};
376 
377  static int selected_tile_mode = 0;
378  static Matrix matrix;
379  if (AiksTest::ImGuiBegin("Controls", nullptr,
380  ImGuiWindowFlags_AlwaysAutoResize)) {
381  ImGui::Combo("Tile mode", &selected_tile_mode, tile_mode_names,
382  sizeof(tile_mode_names) / sizeof(char*));
383  std::string label = "##1";
384  for (int i = 0; i < 4; i++) {
385  ImGui::InputScalarN(label.c_str(), ImGuiDataType_Float,
386  &(matrix.vec[i]), 4, NULL, NULL, "%.2f", 0);
387  label[2]++;
388  }
389  ImGui::End();
390  }
391 
392  DisplayListBuilder builder;
393  DlPaint paint;
394  builder.Translate(100.0, 100.0);
395  auto tile_mode = tile_modes[selected_tile_mode];
396 
397  std::vector<DlColor> colors = {
398  DlColor(Color{0.9568, 0.2627, 0.2118, 1.0}.ToARGB()),
399  DlColor(Color{0.1294, 0.5882, 0.9529, 1.0}.ToARGB())};
400  std::vector<Scalar> stops = {0.0, 1.0};
401 
402  paint.setColorSource(DlColorSource::MakeRadial(
403  {100, 100}, 100, 2, colors.data(), stops.data(), tile_mode));
404 
405  builder.DrawRect(SkRect::MakeXYWH(0, 0, 600, 600), paint);
406  return builder.Build();
407  };
408  ASSERT_TRUE(OpenPlaygroundHere(callback));
409 }

References paint, impeller::Color::ToARGB(), and impeller::Matrix::vec.

◆ TEST_P() [74/456]

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

Definition at line 411 of file aiks_dl_gradient_unittests.cc.

411  {
412  auto callback = [&]() -> sk_sp<DisplayList> {
413  const char* tile_mode_names[] = {"Clamp", "Repeat", "Mirror", "Decal"};
414  const DlTileMode tile_modes[] = {DlTileMode::kClamp, DlTileMode::kRepeat,
415  DlTileMode::kMirror, DlTileMode::kDecal};
416 
417  static int selected_tile_mode = 0;
418  static Matrix matrix = {
419  1, 0, 0, 0, //
420  0, 1, 0, 0, //
421  0, 0, 1, 0, //
422  0, 0, 0, 1 //
423  };
424  if (AiksTest::ImGuiBegin("Controls", nullptr,
425  ImGuiWindowFlags_AlwaysAutoResize)) {
426  ImGui::Combo("Tile mode", &selected_tile_mode, tile_mode_names,
427  sizeof(tile_mode_names) / sizeof(char*));
428  std::string label = "##1";
429  for (int i = 0; i < 4; i++) {
430  ImGui::InputScalarN(label.c_str(), ImGuiDataType_Float,
431  &(matrix.vec[i]), 4, NULL, NULL, "%.2f", 0);
432  label[2]++;
433  }
434  ImGui::End();
435  }
436 
437  DisplayListBuilder builder;
438  DlPaint paint;
439  builder.Translate(100.0, 100.0);
440  auto tile_mode = tile_modes[selected_tile_mode];
441 
442  std::vector<DlColor> colors = {
443  DlColor(Color{0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0}.ToARGB()),
444  DlColor(Color{0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0}.ToARGB()),
445  DlColor(Color{0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0}.ToARGB()),
446  DlColor(Color{0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0}.ToARGB()),
447  DlColor(Color{0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0}.ToARGB()),
448  DlColor(Color{0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0}.ToARGB()),
449  DlColor(Color{0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0}.ToARGB())};
450  std::vector<Scalar> stops = {
451  0.0,
452  (1.0 / 6.0) * 1,
453  (1.0 / 6.0) * 2,
454  (1.0 / 6.0) * 3,
455  (1.0 / 6.0) * 4,
456  (1.0 / 6.0) * 5,
457  1.0,
458  };
459 
460  paint.setColorSource(DlColorSource::MakeRadial(
461  {100, 100}, 100, stops.size(), colors.data(), stops.data(), tile_mode));
462 
463  builder.DrawRect(SkRect::MakeXYWH(0, 0, 600, 600), paint);
464  return builder.Build();
465  };
466  ASSERT_TRUE(OpenPlaygroundHere(callback));
467 }

References paint, impeller::Color::ToARGB(), and impeller::Matrix::vec.

◆ TEST_P() [75/456]

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

Definition at line 140 of file aiks_dl_gradient_unittests.cc.

140  {
142 }

References CanRenderRadialGradientWithDithering().

◆ TEST_P() [76/456]

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

Definition at line 521 of file aiks_unittests.cc.

521  {
522  Canvas canvas;
523 
524  Paint paint;
525  paint.color = Color::Red();
526 
527  PathBuilder::RoundingRadii radii;
528  radii.top_left = {50, 25};
529  radii.top_right = {25, 50};
530  radii.bottom_right = {50, 25};
531  radii.bottom_left = {25, 50};
532 
533  auto path = PathBuilder{}
534  .AddRoundedRect(Rect::MakeXYWH(100, 100, 500, 500), radii)
535  .TakePath();
536 
537  canvas.DrawPath(path, paint);
538 
539  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
540 }

References impeller::PathBuilder::AddRoundedRect(), impeller::PathBuilder::RoundingRadii::bottom_left, impeller::PathBuilder::RoundingRadii::bottom_right, impeller::Canvas::DrawPath(), impeller::Canvas::EndRecordingAsPicture(), impeller::TRect< Scalar >::MakeXYWH(), paint, impeller::Color::Red(), impeller::PathBuilder::TakePath(), impeller::PathBuilder::RoundingRadii::top_left, and impeller::PathBuilder::RoundingRadii::top_right.

◆ TEST_P() [77/456]

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

Definition at line 234 of file aiks_unittests.cc.

234  {
235  Canvas canvas;
236  canvas.Scale(GetContentScale());
237  Paint paint;
238 
239  paint.color = Color::White();
240  canvas.DrawPaint(paint);
241 
242  auto draw = [&canvas](const Paint& paint, Scalar x, Scalar y) {
243  canvas.Save();
244  canvas.Translate({x, y});
245  {
246  canvas.Save();
247  canvas.ClipRect(Rect::MakeLTRB(50, 50, 150, 150));
248  canvas.DrawPaint(paint);
249  canvas.Restore();
250  }
251  {
252  canvas.Save();
253  canvas.ClipOval(Rect::MakeLTRB(200, 50, 300, 150));
254  canvas.DrawPaint(paint);
255  canvas.Restore();
256  }
257  {
258  canvas.Save();
259  canvas.ClipRRect(Rect::MakeLTRB(50, 200, 150, 300), {20, 20});
260  canvas.DrawPaint(paint);
261  canvas.Restore();
262  }
263  {
264  canvas.Save();
265  canvas.ClipRRect(Rect::MakeLTRB(200, 230, 300, 270), {20, 20});
266  canvas.DrawPaint(paint);
267  canvas.Restore();
268  }
269  {
270  canvas.Save();
271  canvas.ClipRRect(Rect::MakeLTRB(230, 200, 270, 300), {20, 20});
272  canvas.DrawPaint(paint);
273  canvas.Restore();
274  }
275  canvas.Restore();
276  };
277 
278  paint.color = Color::Blue();
279  draw(paint, 0, 0);
280 
281  std::vector<Color> gradient_colors = {
282  Color{0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0},
283  Color{0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0},
284  Color{0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0},
285  Color{0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0},
286  Color{0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0},
287  Color{0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0},
288  Color{0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0}};
289  std::vector<Scalar> stops = {
290  0.0,
291  (1.0 / 6.0) * 1,
292  (1.0 / 6.0) * 2,
293  (1.0 / 6.0) * 3,
294  (1.0 / 6.0) * 4,
295  (1.0 / 6.0) * 5,
296  1.0,
297  };
298  auto texture = CreateTextureForFixture("airplane.jpg",
299  /*enable_mipmapping=*/true);
300 
301  paint.color_source = ColorSource::MakeRadialGradient(
302  {500, 600}, 75, std::move(gradient_colors), std::move(stops),
303  Entity::TileMode::kMirror, {});
304  draw(paint, 0, 300);
305 
306  paint.color_source = ColorSource::MakeImage(
307  texture, Entity::TileMode::kRepeat, Entity::TileMode::kRepeat, {},
308  Matrix::MakeTranslation({0, 0}));
309  draw(paint, 300, 0);
310 
311  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
312 }

References impeller::Color::Blue(), impeller::Canvas::ClipOval(), impeller::Canvas::ClipRect(), impeller::Canvas::ClipRRect(), impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), impeller::Entity::kMirror, impeller::Entity::kRepeat, impeller::ColorSource::MakeImage(), impeller::TRect< Scalar >::MakeLTRB(), impeller::ColorSource::MakeRadialGradient(), impeller::Matrix::MakeTranslation(), paint, impeller::Canvas::Restore(), impeller::Canvas::Save(), impeller::Canvas::Scale(), impeller::Canvas::Translate(), and impeller::Color::White().

◆ TEST_P() [78/456]

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

Definition at line 641 of file aiks_unittests.cc.

641  {
642  Canvas canvas;
643  canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)});
644  ASSERT_TRUE(RenderTextInCanvasSkia(
645  GetContext(), canvas, "the quick brown fox jumped over the lazy dog!.?",
646  "Roboto-Regular.ttf",
647  {
648  .stroke = true,
649  }));
650  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
651 }

References impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), and RenderTextInCanvasSkia().

◆ TEST_P() [79/456]

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

Definition at line 63 of file aiks_path_unittests.cc.

63  {
64  Canvas canvas;
65 
66  Paint paint;
67  paint.color = Color::Red();
68  paint.style = Paint::Style::kStroke;
69  paint.stroke_width = 200;
70 
71  Rect rect = Rect::MakeXYWH(100, 100, 200, 200);
72  PathBuilder builder;
73  builder.AddArc(rect, Degrees(0), Degrees(90), false);
74 
75  canvas.DrawPath(builder.TakePath(), paint);
76  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
77 }

References impeller::PathBuilder::AddArc(), impeller::Canvas::DrawPath(), impeller::Canvas::EndRecordingAsPicture(), impeller::Paint::kStroke, impeller::TRect< Scalar >::MakeXYWH(), paint, impeller::Color::Red(), and impeller::PathBuilder::TakePath().

◆ TEST_P() [80/456]

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

Definition at line 79 of file aiks_path_unittests.cc.

79  {
80  Canvas canvas;
81 
82  Paint paint;
83  paint.color = Color::Red();
84  paint.style = Paint::Style::kStroke;
85  paint.stroke_width = 20;
86 
87  PathBuilder builder;
88  builder.AddCubicCurve({0, 200}, {50, 400}, {350, 0}, {400, 200});
89 
90  canvas.DrawPath(builder.TakePath(), paint);
91  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
92 }

References impeller::PathBuilder::AddCubicCurve(), impeller::Canvas::DrawPath(), impeller::Canvas::EndRecordingAsPicture(), impeller::Paint::kStroke, paint, impeller::Color::Red(), and impeller::PathBuilder::TakePath().

◆ TEST_P() [81/456]

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

Definition at line 20 of file aiks_path_unittests.cc.

20  {
21  Canvas canvas;
22  Paint paint;
23  paint.color = Color::Red();
24  paint.stroke_width = 20.0;
25  paint.style = Paint::Style::kStroke;
26  canvas.DrawPath(PathBuilder{}.AddLine({200, 100}, {800, 100}).TakePath(),
27  paint);
28  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
29 }

References impeller::PathBuilder::AddLine(), impeller::Canvas::DrawPath(), impeller::Canvas::EndRecordingAsPicture(), impeller::Paint::kStroke, paint, and impeller::Color::Red().

◆ TEST_P() [82/456]

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

Definition at line 490 of file aiks_dl_gradient_unittests.cc.

490  {
491  CanRenderSweepGradient(this, DlTileMode::kClamp);
492 }

◆ TEST_P() [83/456]

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

Definition at line 499 of file aiks_dl_gradient_unittests.cc.

499  {
500  CanRenderSweepGradient(this, DlTileMode::kDecal);
501 }

◆ TEST_P() [84/456]

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

Definition at line 537 of file aiks_dl_gradient_unittests.cc.

537  {
538  CanRenderSweepGradientManyColors(this, DlTileMode::kClamp);
539 }

◆ TEST_P() [85/456]

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

Definition at line 546 of file aiks_dl_gradient_unittests.cc.

546  {
547  CanRenderSweepGradientManyColors(this, DlTileMode::kDecal);
548 }

◆ TEST_P() [86/456]

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

Definition at line 543 of file aiks_dl_gradient_unittests.cc.

543  {
544  CanRenderSweepGradientManyColors(this, DlTileMode::kMirror);
545 }

◆ TEST_P() [87/456]

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

Definition at line 540 of file aiks_dl_gradient_unittests.cc.

540  {
541  CanRenderSweepGradientManyColors(this, DlTileMode::kRepeat);
542 }

◆ TEST_P() [88/456]

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

Definition at line 496 of file aiks_dl_gradient_unittests.cc.

496  {
497  CanRenderSweepGradient(this, DlTileMode::kMirror);
498 }

◆ TEST_P() [89/456]

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

Definition at line 493 of file aiks_dl_gradient_unittests.cc.

493  {
494  CanRenderSweepGradient(this, DlTileMode::kRepeat);
495 }

◆ TEST_P() [90/456]

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

Definition at line 163 of file aiks_dl_gradient_unittests.cc.

163  {
165 }

References CanRenderSweepGradientWithDithering().

◆ TEST_P() [91/456]

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

Definition at line 620 of file aiks_unittests.cc.

620  {
621  Canvas canvas;
622  canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)});
623  ASSERT_TRUE(RenderTextInCanvasSkia(
624  GetContext(), canvas, "the quick brown fox jumped over the lazy dog!.?",
625  "Roboto-Regular.ttf"));
626  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
627 }

References impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), and RenderTextInCanvasSkia().

◆ TEST_P() [92/456]

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

Definition at line 673 of file aiks_unittests.cc.

673  {
674  Canvas canvas;
675  canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)});
676  ASSERT_TRUE(RenderTextInCanvasSTB(
677  GetContext(), canvas, "the quick brown fox jumped over the lazy dog!.?",
678  "Roboto-Regular.ttf"));
679 
680  SetTypographerContext(TypographerContextSTB::Make());
681  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
682 }

References impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), impeller::TypographerContextSTB::Make(), and RenderTextInCanvasSTB().

◆ TEST_P() [93/456]

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

Definition at line 663 of file aiks_unittests.cc.

663  {
664  Canvas canvas;
665  canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)});
666  canvas.Scale({2.625, 2.625, 1});
667  ASSERT_TRUE(RenderTextInCanvasSkia(
668  GetContext(), canvas, "the quick brown fox jumped over the lazy dog!.?",
669  "Roboto-Regular.ttf"));
670  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
671 }

References impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), RenderTextInCanvasSkia(), and impeller::Canvas::Scale().

◆ TEST_P() [94/456]

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

Definition at line 653 of file aiks_unittests.cc.

653  {
654  Canvas canvas;
655  canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)});
656  canvas.Scale({0.5, 0.5, 1});
657  ASSERT_TRUE(RenderTextInCanvasSkia(
658  GetContext(), canvas, "the quick brown fox jumped over the lazy dog!.?",
659  "Roboto-Regular.ttf"));
660  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
661 }

References impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), RenderTextInCanvasSkia(), and impeller::Canvas::Scale().

◆ TEST_P() [95/456]

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

Definition at line 629 of file aiks_unittests.cc.

629  {
630  Canvas canvas;
631  canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)});
632 
633  canvas.Translate({1000, 0, 0});
634  canvas.Scale({-1, 1, 1});
635  ASSERT_TRUE(RenderTextInCanvasSkia(
636  GetContext(), canvas, "the quick brown fox jumped over the lazy dog!.?",
637  "Roboto-Regular.ttf"));
638  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
639 }

References impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), RenderTextInCanvasSkia(), impeller::Canvas::Scale(), and impeller::Canvas::Translate().

◆ TEST_P() [96/456]

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

Definition at line 779 of file aiks_unittests.cc.

779  {
780  Canvas canvas;
781  canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)});
782 
783  canvas.Translate({100, 100});
784  canvas.Scale(Vector2{0.5, 0.5});
785 
786  // Blend the layer with the parent pass using kClear to expose the coverage.
787  canvas.SaveLayer({.blend_mode = BlendMode::kClear});
788  ASSERT_TRUE(RenderTextInCanvasSkia(
789  GetContext(), canvas, "the quick brown fox jumped over the lazy dog!.?",
790  "Roboto-Regular.ttf"));
791  canvas.Restore();
792 
793  // Render the text again over the cleared coverage rect.
794  ASSERT_TRUE(RenderTextInCanvasSkia(
795  GetContext(), canvas, "the quick brown fox jumped over the lazy dog!.?",
796  "Roboto-Regular.ttf"));
797 
798  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
799 }

References impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), impeller::kClear, RenderTextInCanvasSkia(), impeller::Canvas::Restore(), impeller::Canvas::SaveLayer(), impeller::Canvas::Scale(), and impeller::Canvas::Translate().

◆ TEST_P() [97/456]

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

Definition at line 801 of file aiks_unittests.cc.

801  {
802  Canvas canvas;
803  canvas.Translate({200, 150});
804 
805  // Construct the text blob.
806  auto mapping = flutter::testing::OpenFixtureAsSkData("wtf.otf");
807  ASSERT_NE(mapping, nullptr);
808 
809  Scalar font_size = 80;
810  sk_sp<SkFontMgr> font_mgr = txt::GetDefaultFontManager();
811  SkFont sk_font(font_mgr->makeFromData(mapping), font_size);
812 
813  Paint text_paint;
814  text_paint.color = Color::Blue().WithAlpha(0.8);
815 
816  struct {
817  Point position;
818  const char* text;
819  } text[] = {{Point(0, 0), "0F0F0F0"},
820  {Point(1, 2), "789"},
821  {Point(1, 3), "456"},
822  {Point(1, 4), "123"},
823  {Point(0, 6), "0F0F0F0"}};
824  for (auto& t : text) {
825  canvas.Save();
826  canvas.Translate(t.position * Point(font_size * 2, font_size * 1.1));
827  {
828  auto blob = SkTextBlob::MakeFromString(t.text, sk_font);
829  ASSERT_NE(blob, nullptr);
830  auto frame = MakeTextFrameFromTextBlobSkia(blob);
831  canvas.DrawTextFrame(frame, Point(), text_paint);
832  }
833  canvas.Restore();
834  }
835 
836  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
837 }

References impeller::Color::Blue(), impeller::Paint::color, impeller::Canvas::DrawTextFrame(), impeller::Canvas::EndRecordingAsPicture(), font_size, impeller::MakeTextFrameFromTextBlobSkia(), impeller::Canvas::Restore(), impeller::Canvas::Save(), impeller::Canvas::Translate(), and impeller::Color::WithAlpha().

◆ TEST_P() [98/456]

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

Definition at line 2860 of file aiks_unittests.cc.

2860  {
2861  // Verifies that text scales are clamped to work around
2862  // https://github.com/flutter/flutter/issues/136112 .
2863 
2864  Canvas canvas;
2865  Paint save_paint;
2866  canvas.SaveLayer(save_paint);
2867  canvas.Transform(Matrix(2000, 0, 0, 0, //
2868  0, 2000, 0, 0, //
2869  0, 0, -1, 9000, //
2870  0, 0, -1, 7000 //
2871  ));
2872 
2873  ASSERT_TRUE(RenderTextInCanvasSkia(GetContext(), canvas, "Hello world",
2874  "Roboto-Regular.ttf"));
2875  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2876 }

References impeller::Canvas::EndRecordingAsPicture(), RenderTextInCanvasSkia(), impeller::Canvas::SaveLayer(), and impeller::Canvas::Transform().

◆ TEST_P() [99/456]

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

Definition at line 41 of file aiks_path_unittests.cc.

41  {
42  Canvas canvas;
43  Paint paint;
44  paint.color = Color::Red();
45  paint.stroke_width = 100.0;
46  paint.style = Paint::Style::kStroke;
47  canvas.DrawPath(PathBuilder{}.AddCircle({100, 100}, 50).TakePath(), paint);
48  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
49 }

References impeller::PathBuilder::AddCircle(), impeller::Canvas::DrawPath(), impeller::Canvas::EndRecordingAsPicture(), impeller::Paint::kStroke, paint, and impeller::Color::Red().

◆ TEST_P() [100/456]

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

Definition at line 51 of file aiks_path_unittests.cc.

51  {
52  Canvas canvas;
53  Paint paint;
54  paint.color = Color::Red();
55  // Impeller doesn't support hairlines yet, but size this guarantees
56  // the smallest possible stroke width.
57  paint.stroke_width = 0.01;
58  paint.style = Paint::Style::kStroke;
59  canvas.DrawPath(PathBuilder{}.AddCircle({100, 100}, 50).TakePath(), paint);
60  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
61 }

References impeller::PathBuilder::AddCircle(), impeller::Canvas::DrawPath(), impeller::Canvas::EndRecordingAsPicture(), impeller::Paint::kStroke, paint, and impeller::Color::Red().

◆ TEST_P() [101/456]

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

Definition at line 198 of file aiks_unittests.cc.

198  {
199  CanRenderTiledTexture(this, Entity::TileMode::kClamp);
200 }

References impeller::Entity::kClamp.

◆ TEST_P() [102/456]

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

Definition at line 214 of file aiks_unittests.cc.

214  {
215  CanRenderTiledTexture(this, Entity::TileMode::kClamp,
216  Matrix::MakeTranslation({172.f, 172.f, 0.f}));
217 }

References impeller::Entity::kClamp, and impeller::Matrix::MakeTranslation().

◆ TEST_P() [103/456]

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

Definition at line 210 of file aiks_unittests.cc.

210  {
211  CanRenderTiledTexture(this, Entity::TileMode::kDecal);
212 }

References impeller::Entity::kDecal.

◆ TEST_P() [104/456]

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

Definition at line 206 of file aiks_unittests.cc.

206  {
207  CanRenderTiledTexture(this, Entity::TileMode::kMirror);
208 }

References impeller::Entity::kMirror.

◆ TEST_P() [105/456]

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

Definition at line 202 of file aiks_unittests.cc.

202  {
203  CanRenderTiledTexture(this, Entity::TileMode::kRepeat);
204 }

References impeller::Entity::kRepeat.

◆ TEST_P() [106/456]

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 2120 of file aiks_unittests.cc.

2120  {
2121  Canvas canvas;
2122  canvas.DrawPaint({.color = Color::Red()});
2123 
2124  // Draw two overlapping subpixel circles.
2125  canvas.SaveLayer({});
2126  canvas.DrawCircle({100, 100}, 0.1, {.color = Color::Yellow()});
2127  canvas.Restore();
2128  canvas.SaveLayer({});
2129  canvas.DrawCircle({100, 100}, 0.1, {.color = Color::Yellow()});
2130  canvas.Restore();
2131 
2132  canvas.DrawPaint({.color = Color::Green()});
2133 
2134  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2135 }

References impeller::Canvas::DrawCircle(), impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::Green(), impeller::Color::Red(), impeller::Canvas::Restore(), impeller::Canvas::SaveLayer(), and impeller::Color::Yellow().

◆ TEST_P() [107/456]

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

Definition at line 78 of file aiks_dl_clip_unittests.cc.

78  {
79  DisplayListBuilder builder;
80 
81  // Cover the whole canvas with red.
82  DlPaint paint;
83  paint.setColor(DlColor::kRed());
84  builder.DrawPaint(paint);
85 
86  builder.Save();
87 
88  // Append two clips, the second resulting in empty coverage.
89  builder.ClipRect(SkRect::MakeXYWH(100, 100, 100, 100));
90  builder.ClipRect(SkRect::MakeXYWH(300, 300, 100, 100));
91 
92  // Restore to no clips.
93  builder.Restore();
94 
95  // Replace the whole canvas with green.
96  paint.setColor(DlColor::kGreen());
97  builder.DrawPaint(paint);
98 
99  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
100 }

References paint.

◆ TEST_P() [108/456]

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

Definition at line 314 of file aiks_unittests.cc.

314  {
315  Canvas canvas;
316 
317  Paint red;
318  red.color = Color::Red();
319 
320  Paint alpha;
321  alpha.color = Color::Red().WithAlpha(0.5);
322 
323  canvas.SaveLayer(alpha);
324 
325  canvas.DrawCircle({125, 125}, 125, red);
326 
327  canvas.Restore();
328 
329  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
330 }

References impeller::Paint::color, impeller::Canvas::DrawCircle(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::Red(), impeller::Canvas::Restore(), impeller::Canvas::SaveLayer(), and impeller::Color::WithAlpha().

◆ TEST_P() [109/456]

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

Definition at line 57 of file aiks_unittests.cc.

57  {
58  Canvas canvas;
59  ASSERT_EQ(canvas.GetSaveCount(), 1u);
60  ASSERT_EQ(canvas.Restore(), false);
61 
62  canvas.Translate(Size{100, 100});
63  canvas.Save();
64  ASSERT_EQ(canvas.GetSaveCount(), 2u);
65  ASSERT_MATRIX_NEAR(canvas.GetCurrentTransform(),
66  Matrix::MakeTranslation({100.0, 100.0, 0.0}));
67  ASSERT_TRUE(canvas.Restore());
68  ASSERT_EQ(canvas.GetSaveCount(), 1u);
69  ASSERT_MATRIX_NEAR(canvas.GetCurrentTransform(),
70  Matrix::MakeTranslation({100.0, 100.0, 0.0}));
71 }

References ASSERT_MATRIX_NEAR, impeller::Canvas::GetCurrentTransform(), impeller::Canvas::GetSaveCount(), impeller::Matrix::MakeTranslation(), impeller::Canvas::Restore(), impeller::Canvas::Save(), and impeller::Canvas::Translate().

◆ TEST_P() [110/456]

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

Definition at line 48 of file aiks_unittests.cc.

48  {
49  Canvas canvas;
50  Matrix identity;
51  ASSERT_MATRIX_NEAR(canvas.GetCurrentTransform(), identity);
52  canvas.Translate(Size{100, 100});
53  ASSERT_MATRIX_NEAR(canvas.GetCurrentTransform(),
54  Matrix::MakeTranslation({100.0, 100.0, 0.0}));
55 }

References ASSERT_MATRIX_NEAR, impeller::Canvas::GetCurrentTransform(), impeller::Matrix::MakeTranslation(), and impeller::Canvas::Translate().

◆ TEST_P() [111/456]

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

Definition at line 356 of file aiks_blend_unittests.cc.

356  {
357  Canvas canvas;
358  Paint white;
359  white.color = Color::Blue();
360  canvas.DrawRect(Rect::MakeXYWH(0, 0, 600.0, 600.0), white);
361 
362  Paint clear;
363  clear.blend_mode = BlendMode::kClear;
364 
365  canvas.DrawCircle(Point::MakeXY(300.0, 300.0), 200.0, clear);
366 }

References impeller::Paint::blend_mode, impeller::Color::Blue(), impeller::Paint::color, impeller::Canvas::DrawCircle(), impeller::Canvas::DrawRect(), impeller::kClear, impeller::TPoint< Scalar >::MakeXY(), and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST_P() [112/456]

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

Definition at line 183 of file aiks_blur_unittests.cc.

183  {
184  Canvas canvas;
185  Paint white;
186  white.color = Color::Blue();
187  canvas.DrawRect(Rect::MakeXYWH(0, 0, 600.0, 600.0), white);
188 
189  Paint clear;
190  clear.blend_mode = BlendMode::kClear;
191  clear.mask_blur_descriptor = Paint::MaskBlurDescriptor{
192  .style = FilterContents::BlurStyle::kNormal,
193  .sigma = Sigma(20),
194  };
195 
196  canvas.DrawCircle(Point::MakeXY(300.0, 300.0), 200.0, clear);
197 
198  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
199 }

References impeller::Paint::blend_mode, impeller::Color::Blue(), impeller::Paint::color, impeller::Canvas::DrawCircle(), impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::kClear, impeller::FilterContents::kNormal, impeller::TPoint< Scalar >::MakeXY(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Paint::mask_blur_descriptor, and impeller::Paint::MaskBlurDescriptor::style.

◆ TEST_P() [113/456]

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

Definition at line 1745 of file aiks_unittests.cc.

1745  {
1746  Canvas canvas;
1747  canvas.SaveLayer({}, std::nullopt,
1748  ImageFilter::MakeBlur(Sigma(3), Sigma(3),
1749  FilterContents::BlurStyle::kNormal,
1750  Entity::TileMode::kClamp));
1751  canvas.DrawPaint({.color = Color::Red(), .blend_mode = BlendMode::kSource});
1752  canvas.DrawPaint({.color = Color::CornflowerBlue().WithAlpha(0.75),
1753  .blend_mode = BlendMode::kSourceOver});
1754  canvas.Restore();
1755 
1756  Picture picture = canvas.EndRecordingAsPicture();
1757 
1758  std::optional<Color> actual_color;
1759  bool found_subpass = false;
1760  picture.pass->IterateAllElements([&](EntityPass::Element& element) -> bool {
1761  if (auto subpass = std::get_if<std::unique_ptr<EntityPass>>(&element)) {
1762  actual_color = subpass->get()->GetClearColor();
1763  found_subpass = true;
1764  }
1765  // Fail if the first element isn't a subpass.
1766  return true;
1767  });
1768 
1769  EXPECT_TRUE(found_subpass);
1770  EXPECT_FALSE(actual_color.has_value());
1771 }

References impeller::Color::CornflowerBlue(), impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), impeller::Entity::kClamp, impeller::FilterContents::kNormal, impeller::kSource, impeller::kSourceOver, impeller::ImageFilter::MakeBlur(), impeller::Picture::pass, impeller::Color::Red(), impeller::Canvas::Restore(), impeller::Canvas::SaveLayer(), and impeller::Color::WithAlpha().

◆ TEST_P() [114/456]

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

Definition at line 2549 of file aiks_unittests.cc.

2549  {
2550  SetWindowSize({400, 400});
2551  Canvas canvas;
2552  canvas.Scale(GetContentScale());
2553  canvas.DrawRect(Rect::MakeLTRB(200, 200, 300, 300), {.color = Color::Red()});
2554  canvas.SaveLayer({
2555  .image_filter = std::make_shared<MatrixImageFilter>(
2556  Matrix::MakeScale({2, 2, 1}), SamplerDescriptor{}),
2557  });
2558  // Draw a rectangle that would fully cover the parent pass size, but not
2559  // the subpass that it is rendered in.
2560  canvas.DrawRect(Rect::MakeLTRB(0, 0, 400, 400), {.color = Color::Green()});
2561  // Draw a bigger rectangle to force the subpass to be bigger.
2562  canvas.DrawRect(Rect::MakeLTRB(0, 0, 800, 800), {.color = Color::Red()});
2563  canvas.Restore();
2564 
2565  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2566 }

References impeller::Color::Green(), impeller::TRect< Scalar >::MakeLTRB(), impeller::Matrix::MakeScale(), impeller::Color::Red(), and impeller::Canvas::Scale().

◆ TEST_P() [115/456]

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

Definition at line 168 of file aiks_blur_unittests.cc.

168  {
169  Canvas canvas;
170  canvas.Translate(Point(0, -400));
171  Paint paint;
172  paint.mask_blur_descriptor = Paint::MaskBlurDescriptor{
173  .style = FilterContents::BlurStyle::kNormal,
174  .sigma = Radius{120 * 3},
175  };
176  paint.color = Color::Red();
177  PathBuilder builder{};
178  builder.AddRect(Rect::MakeLTRB(0, 0, 800, 800));
179  canvas.DrawPath(builder.TakePath(), paint);
180  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
181 }

References impeller::PathBuilder::AddRect(), impeller::Canvas::DrawPath(), impeller::Canvas::EndRecordingAsPicture(), impeller::FilterContents::kNormal, impeller::TRect< Scalar >::MakeLTRB(), paint, impeller::Color::Red(), impeller::Paint::MaskBlurDescriptor::style, and impeller::Canvas::Translate().

◆ TEST_P() [116/456]

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

Definition at line 146 of file aiks_blur_unittests.cc.

146  {
147  auto callback = [&](AiksContext& renderer) -> std::optional<Picture> {
148  static PlaygroundPoint playground_point(Point(400, 400), 20,
149  Color::Green());
150  auto point = DrawPlaygroundPoint(playground_point);
151 
152  Canvas canvas;
153  canvas.Translate(point - Point(400, 400));
154  Paint paint;
155  paint.mask_blur_descriptor = Paint::MaskBlurDescriptor{
156  .style = FilterContents::BlurStyle::kNormal,
157  .sigma = Radius{120 * 3},
158  };
159  paint.color = Color::Red();
160  PathBuilder builder{};
161  builder.AddRect(Rect::MakeLTRB(0, 0, 800, 800));
162  canvas.DrawPath(builder.TakePath(), paint);
163  return canvas.EndRecordingAsPicture();
164  };
165  ASSERT_TRUE(OpenPlaygroundHere(callback));
166 }

References impeller::PathBuilder::AddRect(), impeller::Canvas::DrawPath(), impeller::DrawPlaygroundPoint(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::Green(), impeller::FilterContents::kNormal, impeller::TRect< Scalar >::MakeLTRB(), paint, impeller::Color::Red(), impeller::Paint::MaskBlurDescriptor::style, and impeller::Canvas::Translate().

◆ TEST_P() [117/456]

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

Definition at line 1721 of file aiks_unittests.cc.

1721  {
1722  Canvas canvas(Rect::MakeXYWH(0, 0, 100, 100));
1723  canvas.ClipRect(Rect::MakeXYWH(0, 0, 100, 100));
1724  canvas.ClipRect(Rect::MakeXYWH(-100, -100, 300, 300));
1725  canvas.DrawPaint({.color = Color::Red(), .blend_mode = BlendMode::kSource});
1726  canvas.DrawPaint({.color = Color::CornflowerBlue().WithAlpha(0.75),
1727  .blend_mode = BlendMode::kSourceOver});
1728 
1729  Picture picture = canvas.EndRecordingAsPicture();
1730  auto expected = Color::Red().Blend(Color::CornflowerBlue().WithAlpha(0.75),
1731  BlendMode::kSourceOver);
1732  ASSERT_EQ(picture.pass->GetClearColor(), expected);
1733 
1734  std::shared_ptr<ContextSpy> spy = ContextSpy::Make();
1735  std::shared_ptr<Context> real_context = GetContext();
1736  std::shared_ptr<ContextMock> mock_context = spy->MakeContext(real_context);
1737  AiksContext renderer(mock_context, nullptr);
1738  std::shared_ptr<Image> image = picture.ToImage(renderer, {300, 300});
1739 
1740  ASSERT_EQ(spy->render_passes_.size(), 1llu);
1741  std::shared_ptr<RenderPass> render_pass = spy->render_passes_[0];
1742  ASSERT_EQ(render_pass->GetCommands().size(), 0llu);
1743 }

References impeller::Color::Blend(), impeller::Canvas::ClipRect(), impeller::Color::CornflowerBlue(), impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), impeller::kSource, impeller::kSourceOver, impeller::TRect< Scalar >::MakeXYWH(), impeller::Picture::pass, impeller::Color::Red(), impeller::Picture::ToImage(), and impeller::Color::WithAlpha().

◆ TEST_P() [118/456]

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

Definition at line 102 of file aiks_dl_clip_unittests.cc.

102  {
103  std::array<DlColor, 5> colors = {DlColor::kWhite(), DlColor::kBlack(),
104  DlColor::kSkyBlue(), DlColor::kRed(),
105  DlColor::kYellow()};
106  DisplayListBuilder builder;
107  DlPaint paint;
108 
109  builder.Translate(300, 300);
110  for (int i = 0; i < 15; i++) {
111  builder.Scale(0.8, 0.8);
112 
113  paint.setColor(colors[i % colors.size()]);
114  builder.ClipPath(CreateCircle(0, 0, 300));
115  builder.DrawRect(SkRect::MakeXYWH(-300, -300, 600, 600), paint);
116  }
117  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
118 }

References paint.

◆ TEST_P() [119/456]

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

Definition at line 1773 of file aiks_unittests.cc.

1773  {
1774  Canvas canvas;
1775  canvas.DrawPaint(
1776  {.color = Color::Yellow(), .blend_mode = BlendMode::kSource});
1777  canvas.SaveLayer({.blend_mode = BlendMode::kMultiply});
1778  canvas.DrawPaint({.color = Color::CornflowerBlue().WithAlpha(0.75),
1779  .blend_mode = BlendMode::kSourceOver});
1780 
1781  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1782 }

References impeller::Color::CornflowerBlue(), impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), impeller::kMultiply, impeller::kSource, impeller::kSourceOver, impeller::Canvas::SaveLayer(), impeller::Color::WithAlpha(), and impeller::Color::Yellow().

◆ TEST_P() [120/456]

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

Definition at line 1784 of file aiks_unittests.cc.

1784  {
1785  // Bug: https://github.com/flutter/flutter/issues/131576
1786  Canvas canvas;
1787  canvas.DrawPaint(
1788  {.color = Color::Yellow(), .blend_mode = BlendMode::kSource});
1789  canvas.SaveLayer({}, {},
1790  ImageFilter::MakeBlur(Sigma(20.0), Sigma(20.0),
1791  FilterContents::BlurStyle::kNormal,
1792  Entity::TileMode::kDecal));
1793  canvas.DrawPaint(
1794  {.color = Color::CornflowerBlue(), .blend_mode = BlendMode::kSourceOver});
1795 
1796  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1797 }

References impeller::Color::CornflowerBlue(), impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), impeller::Entity::kDecal, impeller::FilterContents::kNormal, impeller::kSource, impeller::kSourceOver, impeller::ImageFilter::MakeBlur(), impeller::Canvas::SaveLayer(), and impeller::Color::Yellow().

◆ TEST_P() [121/456]

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

Definition at line 1799 of file aiks_unittests.cc.

1799  {
1800  Canvas canvas;
1801 
1802  canvas.SaveLayer({
1803  .color_filter =
1804  ColorFilter::MakeMatrix({.array =
1805  {
1806  -1.0, 0, 0, 1.0, 0, //
1807  0, -1.0, 0, 1.0, 0, //
1808  0, 0, -1.0, 1.0, 0, //
1809  1.0, 1.0, 1.0, 1.0, 0 //
1810  }}),
1811  });
1812 
1813  canvas.Translate({500, 300, 0});
1814  canvas.Rotate(Radians(2 * kPi / 3));
1815  canvas.DrawRect(Rect::MakeXYWH(100, 100, 200, 200), {.color = Color::Blue()});
1816 
1817  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1818 }

References impeller::Color::Blue(), impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::kPi, impeller::ColorFilter::MakeMatrix(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Canvas::Rotate(), impeller::Canvas::SaveLayer(), and impeller::Canvas::Translate().

◆ TEST_P() [122/456]

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 205 of file aiks_blend_unittests.cc.

205  {
206  // Compare with https://fiddle.skia.org/c/@BlendModes
207 
208  BlendModeSelection blend_modes = GetBlendModeSelection();
209 
210  auto draw_color_wheel = [](Canvas& canvas) {
211  /// color_wheel_sampler: r=0 -> fuchsia, r=2pi/3 -> yellow, r=4pi/3 ->
212  /// cyan domain: r >= 0 (because modulo used is non euclidean)
213  auto color_wheel_sampler = [](Radians r) {
214  Scalar x = r.radians / k2Pi + 1;
215 
216  // https://www.desmos.com/calculator/6nhjelyoaj
217  auto color_cycle = [](Scalar x) {
218  Scalar cycle = std::fmod(x, 6.0f);
219  return std::max(0.0f, std::min(1.0f, 2 - std::abs(2 - cycle)));
220  };
221  return Color(color_cycle(6 * x + 1), //
222  color_cycle(6 * x - 1), //
223  color_cycle(6 * x - 3), //
224  1);
225  };
226 
227  Paint paint;
228  paint.blend_mode = BlendMode::kSourceOver;
229 
230  // Draw a fancy color wheel for the backdrop.
231  // https://www.desmos.com/calculator/xw7kafthwd
232  const int max_dist = 900;
233  for (int i = 0; i <= 900; i++) {
234  Radians r(kPhi / k2Pi * i);
235  Scalar distance = r.radians / std::powf(4.12, 0.0026 * r.radians);
236  Scalar normalized_distance = static_cast<Scalar>(i) / max_dist;
237 
238  paint.color =
239  color_wheel_sampler(r).WithAlpha(1.0f - normalized_distance);
240  Point position(distance * std::sin(r.radians),
241  -distance * std::cos(r.radians));
242 
243  canvas.DrawCircle(position, 9 + normalized_distance * 3, paint);
244  }
245  };
246 
247  std::shared_ptr<Image> color_wheel_image;
248  Matrix color_wheel_transform;
249 
250  auto callback = [&](AiksContext& renderer) -> std::optional<Picture> {
251  // UI state.
252  static bool cache_the_wheel = true;
253  static int current_blend_index = 3;
254  static float dst_alpha = 1;
255  static float src_alpha = 1;
256  static Color color0 = Color::Red();
257  static Color color1 = Color::Green();
258  static Color color2 = Color::Blue();
259 
260  if (AiksTest::ImGuiBegin("Controls", nullptr,
261  ImGuiWindowFlags_AlwaysAutoResize)) {
262  ImGui::Checkbox("Cache the wheel", &cache_the_wheel);
263  ImGui::ListBox("Blending mode", &current_blend_index,
264  blend_modes.blend_mode_names.data(),
265  blend_modes.blend_mode_names.size());
266  ImGui::SliderFloat("Source alpha", &src_alpha, 0, 1);
267  ImGui::ColorEdit4("Color A", reinterpret_cast<float*>(&color0));
268  ImGui::ColorEdit4("Color B", reinterpret_cast<float*>(&color1));
269  ImGui::ColorEdit4("Color C", reinterpret_cast<float*>(&color2));
270  ImGui::SliderFloat("Destination alpha", &dst_alpha, 0, 1);
271  ImGui::End();
272  }
273 
274  static Point content_scale;
275  Point new_content_scale = GetContentScale();
276 
277  if (!cache_the_wheel || new_content_scale != content_scale) {
278  content_scale = new_content_scale;
279 
280  // Render the color wheel to an image.
281 
282  Canvas canvas;
283  canvas.Scale(content_scale);
284 
285  canvas.Translate(Vector2(500, 400));
286  canvas.Scale(Vector2(3, 3));
287 
288  draw_color_wheel(canvas);
289  auto color_wheel_picture = canvas.EndRecordingAsPicture();
290  auto snapshot = color_wheel_picture.Snapshot(renderer);
291  if (!snapshot.has_value() || !snapshot->texture) {
292  return std::nullopt;
293  }
294  color_wheel_image = std::make_shared<Image>(snapshot->texture);
295  color_wheel_transform = snapshot->transform;
296  }
297 
298  Canvas canvas;
299 
300  // Blit the color wheel backdrop to the screen with managed alpha.
301  canvas.SaveLayer({.color = Color::White().WithAlpha(dst_alpha),
302  .blend_mode = BlendMode::kSource});
303  {
304  canvas.DrawPaint({.color = Color::White()});
305 
306  canvas.Save();
307  canvas.Transform(color_wheel_transform);
308  canvas.DrawImage(color_wheel_image, Point(), Paint());
309  canvas.Restore();
310  }
311  canvas.Restore();
312 
313  canvas.Scale(content_scale);
314  canvas.Translate(Vector2(500, 400));
315  canvas.Scale(Vector2(3, 3));
316 
317  // Draw 3 circles to a subpass and blend it in.
318  canvas.SaveLayer(
319  {.color = Color::White().WithAlpha(src_alpha),
320  .blend_mode = blend_modes.blend_mode_values[current_blend_index]});
321  {
322  Paint paint;
323  paint.blend_mode = BlendMode::kPlus;
324  const Scalar x = std::sin(k2Pi / 3);
325  const Scalar y = -std::cos(k2Pi / 3);
326  paint.color = color0;
327  canvas.DrawCircle(Point(-x, y) * 45, 65, paint);
328  paint.color = color1;
329  canvas.DrawCircle(Point(0, -1) * 45, 65, paint);
330  paint.color = color2;
331  canvas.DrawCircle(Point(x, y) * 45, 65, paint);
332  }
333  canvas.Restore();
334 
335  return canvas.EndRecordingAsPicture();
336  };
337 
338  ASSERT_TRUE(OpenPlaygroundHere(callback));
339 }

References impeller::testing::BlendModeSelection::blend_mode_names, impeller::testing::BlendModeSelection::blend_mode_values, impeller::Color::Blue(), impeller::saturated::distance, impeller::Canvas::DrawCircle(), impeller::Canvas::DrawImage(), impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), GetBlendModeSelection(), impeller::Color::Green(), impeller::AiksPlayground::ImGuiBegin(), impeller::k2Pi, impeller::kPhi, impeller::kPlus, impeller::kSource, impeller::kSourceOver, paint, impeller::Radians::radians, impeller::Color::Red(), impeller::Canvas::Restore(), impeller::Canvas::Save(), impeller::Canvas::SaveLayer(), impeller::Canvas::Scale(), impeller::Picture::Snapshot(), impeller::Canvas::Transform(), impeller::Canvas::Translate(), impeller::Color::White(), and impeller::Color::WithAlpha().

◆ TEST_P() [123/456]

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

Definition at line 404 of file aiks_unittests.cc.

404  {
405  Canvas canvas;
406 
407  // Render a texture directly.
408  {
409  Paint paint;
410  auto image =
411  std::make_shared<Image>(CreateTextureForFixture("kalimba.jpg"));
412  paint.color = Color::Red();
413 
414  canvas.Save();
415  canvas.Translate({100, 200, 0});
416  canvas.Scale(Vector2{0.5, 0.5});
417  canvas.DrawImage(image, Point::MakeXY(100.0, 100.0), paint);
418  canvas.Restore();
419  }
420 
421  // Render an offscreen rendered texture.
422  {
423  Paint red;
424  red.color = Color::Red();
425  Paint green;
426  green.color = Color::Green();
427  Paint blue;
428  blue.color = Color::Blue();
429 
430  Paint alpha;
431  alpha.color = Color::Red().WithAlpha(0.5);
432 
433  canvas.SaveLayer(alpha);
434 
435  canvas.DrawRect(Rect::MakeXYWH(000, 000, 100, 100), red);
436  canvas.DrawRect(Rect::MakeXYWH(020, 020, 100, 100), green);
437  canvas.DrawRect(Rect::MakeXYWH(040, 040, 100, 100), blue);
438 
439  canvas.Restore();
440  }
441 
442  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
443 }

References impeller::Color::Blue(), impeller::Paint::color, impeller::Canvas::DrawImage(), impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::Green(), impeller::TPoint< Scalar >::MakeXY(), impeller::TRect< Scalar >::MakeXYWH(), paint, impeller::Color::Red(), impeller::Canvas::Restore(), impeller::Canvas::Save(), impeller::Canvas::SaveLayer(), impeller::Canvas::Scale(), impeller::Canvas::Translate(), and impeller::Color::WithAlpha().

◆ TEST_P() [124/456]

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

Definition at line 2658 of file aiks_unittests.cc.

2658  {
2659  Canvas canvas; // Depth 1 (base pass)
2660  canvas.DrawRRect(Rect::MakeLTRB(0, 0, 100, 100), {10, 10}, {}); // Depth 2
2661  canvas.Save();
2662  {
2663  canvas.ClipRRect(Rect::MakeLTRB(0, 0, 50, 50), {10, 10}, {}); // Depth 4
2664  canvas.SaveLayer({}); // Depth 4
2665  {
2666  canvas.DrawRRect(Rect::MakeLTRB(0, 0, 50, 50), {10, 10}, {}); // Depth 3
2667  }
2668  canvas.Restore(); // Restore the savelayer.
2669  }
2670  canvas.Restore(); // Depth 5 -- this will no longer append a restore entity
2671  // once we switch to the clip depth approach.
2672 
2673  auto picture = canvas.EndRecordingAsPicture();
2674 
2675  std::vector<uint32_t> expected = {
2676  2, // DrawRRect
2677  4, // ClipRRect -- Has a depth value equal to the max depth of all the
2678  // content it affect. In this case, the SaveLayer and all
2679  // its contents are affected.
2680  4, // SaveLayer -- The SaveLayer is drawn to the parent pass after its
2681  // contents are rendered, so it should have a depth value
2682  // greater than all its contents.
2683  3, // DrawRRect
2684  5, // Restore (no longer necessary when clipping on the depth buffer)
2685  };
2686 
2687  std::vector<uint32_t> actual;
2688 
2689  picture.pass->IterateAllElements([&](EntityPass::Element& element) -> bool {
2690  if (auto* subpass = std::get_if<std::unique_ptr<EntityPass>>(&element)) {
2691  actual.push_back(subpass->get()->GetClipDepth());
2692  }
2693  if (Entity* entity = std::get_if<Entity>(&element)) {
2694  actual.push_back(entity->GetClipDepth());
2695  }
2696  return true;
2697  });
2698 
2699  ASSERT_EQ(actual.size(), expected.size());
2700  for (size_t i = 0; i < expected.size(); i++) {
2701  EXPECT_EQ(expected[i], actual[i]) << "Index: " << i;
2702  }
2703 }

References impeller::Canvas::ClipRRect(), impeller::Canvas::DrawRRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::TRect< Scalar >::MakeLTRB(), impeller::Picture::pass, impeller::Canvas::Restore(), impeller::Canvas::Save(), and impeller::Canvas::SaveLayer().

◆ TEST_P() [125/456]

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

Definition at line 1377 of file aiks_unittests.cc.

1377  {
1378  auto callback = [&](AiksContext& renderer) -> std::optional<Picture> {
1379  Canvas canvas;
1380  canvas.Scale(GetContentScale());
1381 
1382  Paint alpha;
1383  alpha.color = Color::Red().WithAlpha(0.5);
1384 
1385  auto current = Point{25, 25};
1386  const auto offset = Point{25, 25};
1387  const auto size = Size(100, 100);
1388 
1389  static PlaygroundPoint point_a(Point(40, 40), 10, Color::White());
1390  static PlaygroundPoint point_b(Point(160, 160), 10, Color::White());
1391  auto [b0, b1] = DrawPlaygroundLine(point_a, point_b);
1392  auto bounds = Rect::MakeLTRB(b0.x, b0.y, b1.x, b1.y);
1393 
1394  canvas.DrawRect(bounds, Paint{.color = Color::Yellow(),
1395  .stroke_width = 5.0f,
1396  .style = Paint::Style::kStroke});
1397 
1398  canvas.SaveLayer(alpha, bounds);
1399 
1400  canvas.DrawRect(Rect::MakeOriginSize(current, size),
1401  Paint{.color = Color::Red()});
1402  canvas.DrawRect(Rect::MakeOriginSize(current += offset, size),
1403  Paint{.color = Color::Green()});
1404  canvas.DrawRect(Rect::MakeOriginSize(current += offset, size),
1405  Paint{.color = Color::Blue()});
1406 
1407  canvas.Restore();
1408 
1409  return canvas.EndRecordingAsPicture();
1410  };
1411 
1412  ASSERT_TRUE(OpenPlaygroundHere(callback));
1413 }

References impeller::Color::Blue(), impeller::Paint::color, impeller::DrawPlaygroundLine(), impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::Green(), impeller::Paint::kStroke, impeller::TRect< Scalar >::MakeLTRB(), impeller::TRect< Scalar >::MakeOriginSize(), offset, impeller::Color::Red(), impeller::Canvas::Restore(), impeller::Canvas::SaveLayer(), impeller::Canvas::Scale(), impeller::Color::White(), impeller::Color::WithAlpha(), and impeller::Color::Yellow().

◆ TEST_P() [126/456]

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

Definition at line 94 of file aiks_blend_unittests.cc.

94  {
95  std::vector<Color> colors = {Color{0.9568, 0.2627, 0.2118, 1.0},
96  Color{0.1294, 0.5882, 0.9529, 1.0}};
97  std::vector<Scalar> stops = {0.0, 1.0};
98 
99  Paint paint = {
100  .color_source = ColorSource::MakeLinearGradient(
101  {0, 0}, {100, 100}, std::move(colors), std::move(stops),
102  Entity::TileMode::kRepeat, Matrix::MakeScale(Vector3(0.3, 0.3, 0.3))),
103  .blend_mode = BlendMode::kLighten,
104  };
105 
106  Canvas canvas;
107  canvas.DrawPaint({.color = Color::Blue()});
108  canvas.Scale(Vector2(2, 2));
109  canvas.ClipRect(Rect::MakeLTRB(0, 0, 200, 200));
110  canvas.DrawCircle({100, 100}, 100, paint);
111  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
112 }

References impeller::Color::Blue(), impeller::Canvas::ClipRect(), impeller::Canvas::DrawCircle(), impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), impeller::kLighten, impeller::Entity::kRepeat, impeller::ColorSource::MakeLinearGradient(), impeller::TRect< Scalar >::MakeLTRB(), impeller::Matrix::MakeScale(), paint, and impeller::Canvas::Scale().

◆ TEST_P() [127/456]

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

Definition at line 129 of file aiks_dl_atlas_unittests.cc.

129  {
130  DisplayListBuilder builder;
131  // Draws the image as four squares stiched together.
132  auto [texture_coordinates, transforms, atlas] = CreateTestData(this);
133 
134  builder.Scale(0.25, 0.25);
135  builder.DrawAtlas(atlas, transforms.data(), texture_coordinates.data(),
136  /*colors=*/nullptr, /*count=*/4, DlBlendMode::kModulate,
137  DlImageSampling::kNearestNeighbor, /*cullRect=*/nullptr);
138 
139  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
140 }

◆ TEST_P() [128/456]

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

Definition at line 52 of file aiks_dl_atlas_unittests.cc.

52  {
53  DisplayListBuilder builder;
54  auto [texture_coordinates, transforms, atlas] = CreateTestData(this);
55 
56  builder.Scale(GetContentScale().x, GetContentScale().y);
57  builder.DrawAtlas(atlas, transforms.data(), texture_coordinates.data(),
58  /*colors=*/nullptr, /*count=*/4, DlBlendMode::kSrcOver,
59  DlImageSampling::kNearestNeighbor, nullptr);
60 
61  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
62 }

◆ TEST_P() [129/456]

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

Definition at line 112 of file aiks_dl_atlas_unittests.cc.

112  {
113  auto atlas = DlImageImpeller::Make(CreateTextureForFixture("bay_bridge.jpg"));
114  auto size = atlas->impeller_texture()->GetSize();
115  std::vector<SkRect> texture_coordinates = {
116  SkRect::MakeLTRB(0, 0, size.width, size.height)};
117  std::vector<SkRSXform> transforms = {MakeTranslation(0, 0)};
118 
119  DisplayListBuilder builder;
120  builder.Scale(GetContentScale().x, GetContentScale().y);
121  builder.DrawAtlas(atlas, transforms.data(), texture_coordinates.data(),
122  /*colors=*/nullptr, /*count=*/1, DlBlendMode::kSrcOver,
123  DlImageSampling::kNearestNeighbor, /*cullRect=*/nullptr);
124 
125  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
126 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [130/456]

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

Definition at line 158 of file aiks_dl_atlas_unittests.cc.

158  {
159  DisplayListBuilder builder;
160  EXPECT_EQ(GetContext()->GetCapabilities()->GetDefaultColorFormat(),
161  PixelFormat::kB10G10R10A10XR);
162 
163  // Draws the image as four squares stiched together.
164  auto [texture_coordinates, transforms, atlas] = CreateTestData(this);
165  std::vector<DlColor> colors = {DlColor::kRed(), DlColor::kGreen(),
166  DlColor::kBlue(), DlColor::kYellow()};
167 
168  builder.DrawAtlas(atlas, transforms.data(), texture_coordinates.data(),
169  colors.data(), /*count=*/4, DlBlendMode::kPlus,
170  DlImageSampling::kNearestNeighbor, /*cullRect=*/nullptr);
171 
172  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
173 }

References impeller::kB10G10R10A10XR.

◆ TEST_P() [131/456]

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

Definition at line 64 of file aiks_dl_atlas_unittests.cc.

64  {
65  DisplayListBuilder builder;
66  auto [texture_coordinates, transforms, atlas] = CreateTestData(this);
67 
68  std::vector<DlColor> colors = {DlColor::kRed(), DlColor::kGreen(),
69  DlColor::kBlue(), DlColor::kYellow()};
70 
71  builder.Scale(GetContentScale().x, GetContentScale().y);
72  builder.DrawAtlas(atlas, transforms.data(), texture_coordinates.data(),
73  colors.data(), /*count=*/4, DlBlendMode::kModulate,
74  DlImageSampling::kNearestNeighbor, /*cullRect=*/nullptr);
75 
76  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
77 }

◆ TEST_P() [132/456]

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

Definition at line 143 of file aiks_dl_atlas_unittests.cc.

143  {
144  DisplayListBuilder builder;
145  // Draws the image as four squares stiched together.
146  auto [texture_coordinates, transforms, atlas] = CreateTestData(this);
147  std::vector<DlColor> colors = {DlColor::kRed(), DlColor::kGreen(),
148  DlColor::kBlue(), DlColor::kYellow()};
149 
150  builder.Scale(0.25, 0.25);
151  builder.DrawAtlas(atlas, transforms.data(), texture_coordinates.data(),
152  colors.data(), /*count=*/4, DlBlendMode::kModulate,
153  DlImageSampling::kNearestNeighbor, /*cullRect=*/nullptr);
154 
155  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
156 }

◆ TEST_P() [133/456]

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

Definition at line 79 of file aiks_dl_atlas_unittests.cc.

79  {
80  DisplayListBuilder builder;
81  // Draws the image as four squares stiched together.
82  auto [texture_coordinates, transforms, atlas] = CreateTestData(this);
83 
84  std::vector<DlColor> colors = {DlColor::kRed(), DlColor::kGreen(),
85  DlColor::kBlue(), DlColor::kYellow()};
86 
87  builder.Scale(GetContentScale().x, GetContentScale().y);
88  builder.DrawAtlas(atlas, transforms.data(), texture_coordinates.data(),
89  colors.data(), /*count=*/4, DlBlendMode::kSrcATop,
90  DlImageSampling::kNearestNeighbor, /*cullRect=*/nullptr);
91 
92  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
93 }

◆ TEST_P() [134/456]

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

Definition at line 95 of file aiks_dl_atlas_unittests.cc.

95  {
96  DisplayListBuilder builder;
97  // Draws the image as four squares stiched together slightly
98  // opaque
99  auto [texture_coordinates, transforms, atlas] = CreateTestData(this);
100 
101  DlPaint paint;
102  paint.setAlpha(128);
103  builder.Scale(GetContentScale().x, GetContentScale().y);
104  builder.DrawAtlas(atlas, transforms.data(), texture_coordinates.data(),
105  /*colors=*/nullptr, 4, DlBlendMode::kSrcOver,
106  DlImageSampling::kNearestNeighbor, /*cullRect=*/nullptr,
107  &paint);
108 
109  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
110 }

References paint.

◆ TEST_P() [135/456]

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

Definition at line 256 of file aiks_path_unittests.cc.

256  {
257  Canvas canvas;
258  canvas.Scale(GetContentScale());
259  Paint paint;
260  paint.color = Color::Blue();
261  paint.stroke_width = 10;
262 
263  auto draw = [&canvas](Paint& paint) {
264  for (auto cap : {Cap::kButt, Cap::kSquare, Cap::kRound}) {
265  paint.stroke_cap = cap;
266  Point origin = {100, 100};
267  Point p0 = {50, 0};
268  Point p1 = {150, 0};
269  canvas.DrawLine({150, 100}, {250, 100}, paint);
270  for (int d = 15; d < 90; d += 15) {
271  Matrix m = Matrix::MakeRotationZ(Degrees(d));
272  canvas.DrawLine(origin + m * p0, origin + m * p1, paint);
273  }
274  canvas.DrawLine({100, 150}, {100, 250}, paint);
275  canvas.DrawCircle({origin}, 35, paint);
276 
277  canvas.DrawLine({250, 250}, {250, 250}, paint);
278 
279  canvas.Translate({250, 0});
280  }
281  canvas.Translate({-750, 250});
282  };
283 
284  std::vector<Color> colors = {
285  Color{0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0},
286  Color{0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0},
287  Color{0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0},
288  Color{0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0},
289  Color{0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0},
290  Color{0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0},
291  Color{0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0}};
292  std::vector<Scalar> stops = {
293  0.0,
294  (1.0 / 6.0) * 1,
295  (1.0 / 6.0) * 2,
296  (1.0 / 6.0) * 3,
297  (1.0 / 6.0) * 4,
298  (1.0 / 6.0) * 5,
299  1.0,
300  };
301 
302  auto texture = CreateTextureForFixture("airplane.jpg",
303  /*enable_mipmapping=*/true);
304 
305  draw(paint);
306 
307  paint.color_source = ColorSource::MakeRadialGradient(
308  {100, 100}, 200, std::move(colors), std::move(stops),
309  Entity::TileMode::kMirror, {});
310  draw(paint);
311 
312  paint.color_source = ColorSource::MakeImage(
313  texture, Entity::TileMode::kRepeat, Entity::TileMode::kRepeat, {},
314  Matrix::MakeTranslation({-150, 75}));
315  draw(paint);
316 
317  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
318 }

References impeller::Color::Blue(), impeller::Canvas::DrawCircle(), impeller::Canvas::DrawLine(), impeller::Canvas::EndRecordingAsPicture(), impeller::kButt, impeller::Entity::kMirror, impeller::Entity::kRepeat, impeller::kRound, impeller::kSquare, impeller::ColorSource::MakeImage(), impeller::ColorSource::MakeRadialGradient(), impeller::Matrix::MakeRotationZ(), impeller::Matrix::MakeTranslation(), paint, impeller::Canvas::Scale(), and impeller::Canvas::Translate().

◆ TEST_P() [136/456]

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

Definition at line 19 of file aiks_dl_opacity_unittests.cc.

19  {
20  DisplayListBuilder builder;
21 
22  DlPaint green;
23  green.setColor(DlColor::kGreen().modulateOpacity(0.5));
24 
25  DlPaint alpha;
26  alpha.setColor(DlColor::kRed().modulateOpacity(0.5));
27 
28  builder.SaveLayer(nullptr, &alpha);
29  builder.DrawRect(SkRect::MakeXYWH(0, 0, 100, 100), green);
30  builder.Restore();
31 
32  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
33 }

◆ TEST_P() [137/456]

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

Definition at line 1594 of file aiks_unittests.cc.

1594  {
1595  Canvas canvas;
1596  canvas.DrawPaint({.color = Color::Red(), .blend_mode = BlendMode::kSource});
1597  canvas.DrawPaint({.color = Color::CornflowerBlue().WithAlpha(0.75),
1598  .blend_mode = BlendMode::kSourceOver});
1599 
1600  Picture picture = canvas.EndRecordingAsPicture();
1601  auto expected = Color::Red().Blend(Color::CornflowerBlue().WithAlpha(0.75),
1602  BlendMode::kSourceOver);
1603  ASSERT_EQ(picture.pass->GetClearColor(), expected);
1604 
1605  std::shared_ptr<ContextSpy> spy = ContextSpy::Make();
1606  std::shared_ptr<Context> real_context = GetContext();
1607  std::shared_ptr<ContextMock> mock_context = spy->MakeContext(real_context);
1608  AiksContext renderer(mock_context, nullptr);
1609  std::shared_ptr<Image> image = picture.ToImage(renderer, {300, 300});
1610 
1611  ASSERT_EQ(spy->render_passes_.size(), 1llu);
1612  std::shared_ptr<RenderPass> render_pass = spy->render_passes_[0];
1613  ASSERT_EQ(render_pass->GetCommands().size(), 0llu);
1614 }

References impeller::Color::Blend(), impeller::Color::CornflowerBlue(), impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), impeller::kSource, impeller::kSourceOver, impeller::Picture::pass, impeller::Color::Red(), impeller::Picture::ToImage(), and impeller::Color::WithAlpha().

◆ TEST_P() [138/456]

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

Definition at line 2214 of file aiks_unittests.cc.

2214  {
2215  auto runtime_stages = OpenAssetAsRuntimeStage("gradient.frag.iplr");
2216  auto runtime_stage =
2217  runtime_stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
2218  ASSERT_TRUE(runtime_stage);
2219  ASSERT_TRUE(runtime_stage->IsDirty());
2220 
2221  struct FragUniforms {
2222  Size size;
2223  } frag_uniforms = {.size = Size::MakeWH(400, 400)};
2224  auto uniform_data = std::make_shared<std::vector<uint8_t>>();
2225  uniform_data->resize(sizeof(FragUniforms));
2226  memcpy(uniform_data->data(), &frag_uniforms, sizeof(FragUniforms));
2227 
2228  std::vector<RuntimeEffectContents::TextureInput> texture_inputs;
2229 
2230  Paint paint;
2231  paint.color_source = ColorSource::MakeRuntimeEffect(
2232  runtime_stage, uniform_data, texture_inputs);
2233 
2234  Canvas canvas;
2235  canvas.Save();
2236  canvas.Scale(GetContentScale());
2237  canvas.DrawPaint(paint);
2238  canvas.Restore();
2239 
2240  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2241 }

References impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), impeller::ColorSource::MakeRuntimeEffect(), impeller::TSize< Scalar >::MakeWH(), paint, impeller::PlaygroundBackendToRuntimeStageBackend(), impeller::Canvas::Restore(), impeller::Canvas::Save(), and impeller::Canvas::Scale().

◆ TEST_P() [139/456]

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

Definition at line 77 of file aiks_blend_unittests.cc.

77  {
78  Paint filtered = {
79  .color = Color::Black(),
80  .mask_blur_descriptor =
81  Paint::MaskBlurDescriptor{
82  .style = FilterContents::BlurStyle::kNormal,
83  .sigma = Sigma(60),
84  },
85  };
86 
87  Canvas canvas;
88  canvas.DrawPaint({.color = Color::White()});
89  canvas.DrawCircle({300, 300}, 200, filtered);
90  canvas.DrawPaint({.color = Color::Green(), .blend_mode = BlendMode::kScreen});
91  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
92 }

References impeller::Color::Black(), impeller::Paint::color, impeller::Canvas::DrawCircle(), impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::Green(), impeller::FilterContents::kNormal, impeller::kScreen, impeller::Paint::MaskBlurDescriptor::style, and impeller::Color::White().

◆ TEST_P() [140/456]

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

Definition at line 1641 of file aiks_unittests.cc.

1641  {
1642  Canvas canvas;
1643  canvas.DrawRect(Rect::MakeXYWH(0, 0, 300, 300),
1644  {.color = Color::Red(), .blend_mode = BlendMode::kSource});
1645  canvas.DrawRect(Rect::MakeXYWH(0, 0, 300, 300),
1646  {.color = Color::CornflowerBlue().WithAlpha(0.75),
1647  .blend_mode = BlendMode::kSourceOver});
1648 
1649  std::shared_ptr<ContextSpy> spy = ContextSpy::Make();
1650  Picture picture = canvas.EndRecordingAsPicture();
1651  std::shared_ptr<Context> real_context = GetContext();
1652  std::shared_ptr<ContextMock> mock_context = spy->MakeContext(real_context);
1653  AiksContext renderer(mock_context, nullptr);
1654  std::shared_ptr<Image> image = picture.ToImage(renderer, {300, 300});
1655 
1656  ASSERT_EQ(spy->render_passes_.size(), 1llu);
1657  std::shared_ptr<RenderPass> render_pass = spy->render_passes_[0];
1658  ASSERT_EQ(render_pass->GetCommands().size(), 0llu);
1659 }

References impeller::Color::CornflowerBlue(), impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::kSource, impeller::kSourceOver, impeller::TRect< Scalar >::MakeXYWH(), impeller::Color::Red(), impeller::Picture::ToImage(), and impeller::Color::WithAlpha().

◆ TEST_P() [141/456]

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

Definition at line 1701 of file aiks_unittests.cc.

1701  {
1702  Canvas canvas;
1703  canvas.DrawRect(Rect::MakeXYWH(0, 0, 300, 300),
1704  {.color = Color::Red(), .blend_mode = BlendMode::kSource});
1705  canvas.DrawRect(Rect::MakeXYWH(0, 0, 300, 300),
1706  {.color = Color::CornflowerBlue().WithAlpha(0.75),
1707  .blend_mode = BlendMode::kSourceOver});
1708 
1709  std::shared_ptr<ContextSpy> spy = ContextSpy::Make();
1710  Picture picture = canvas.EndRecordingAsPicture();
1711  std::shared_ptr<Context> real_context = GetContext();
1712  std::shared_ptr<ContextMock> mock_context = spy->MakeContext(real_context);
1713  AiksContext renderer(mock_context, nullptr);
1714  std::shared_ptr<Image> image = picture.ToImage(renderer, {301, 301});
1715 
1716  ASSERT_EQ(spy->render_passes_.size(), 1llu);
1717  std::shared_ptr<RenderPass> render_pass = spy->render_passes_[0];
1718  ASSERT_EQ(render_pass->GetCommands().size(), 2llu);
1719 }

References impeller::Color::CornflowerBlue(), impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::kSource, impeller::kSourceOver, impeller::TRect< Scalar >::MakeXYWH(), impeller::Color::Red(), impeller::Picture::ToImage(), and impeller::Color::WithAlpha().

◆ TEST_P() [142/456]

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

Definition at line 1681 of file aiks_unittests.cc.

1681  {
1682  Canvas canvas;
1683  canvas.Translate(Vector3(150.0, 150.0, 0.0));
1684  canvas.Rotate(Degrees(45.0));
1685  canvas.Translate(Vector3(-150.0, -150.0, 0.0));
1686  canvas.DrawRect(Rect::MakeXYWH(0, 0, 300, 300),
1687  {.color = Color::Red(), .blend_mode = BlendMode::kSource});
1688 
1689  std::shared_ptr<ContextSpy> spy = ContextSpy::Make();
1690  Picture picture = canvas.EndRecordingAsPicture();
1691  std::shared_ptr<Context> real_context = GetContext();
1692  std::shared_ptr<ContextMock> mock_context = spy->MakeContext(real_context);
1693  AiksContext renderer(mock_context, nullptr);
1694  std::shared_ptr<Image> image = picture.ToImage(renderer, {300, 300});
1695 
1696  ASSERT_EQ(spy->render_passes_.size(), 1llu);
1697  std::shared_ptr<RenderPass> render_pass = spy->render_passes_[0];
1698  ASSERT_EQ(render_pass->GetCommands().size(), 1llu);
1699 }

References impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::kSource, impeller::TRect< Scalar >::MakeXYWH(), impeller::Color::Red(), impeller::Canvas::Rotate(), impeller::Picture::ToImage(), and impeller::Canvas::Translate().

◆ TEST_P() [143/456]

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

Definition at line 1661 of file aiks_unittests.cc.

1661  {
1662  Canvas canvas;
1663  canvas.DrawRRect(Rect::MakeXYWH(0, 0, 300, 300), {5.0, 5.0},
1664  {.color = Color::Red(), .blend_mode = BlendMode::kSource});
1665  canvas.DrawRRect(Rect::MakeXYWH(0, 0, 300, 300), {5.0, 5.0},
1666  {.color = Color::CornflowerBlue().WithAlpha(0.75),
1667  .blend_mode = BlendMode::kSourceOver});
1668 
1669  std::shared_ptr<ContextSpy> spy = ContextSpy::Make();
1670  Picture picture = canvas.EndRecordingAsPicture();
1671  std::shared_ptr<Context> real_context = GetContext();
1672  std::shared_ptr<ContextMock> mock_context = spy->MakeContext(real_context);
1673  AiksContext renderer(mock_context, nullptr);
1674  std::shared_ptr<Image> image = picture.ToImage(renderer, {300, 300});
1675 
1676  ASSERT_EQ(spy->render_passes_.size(), 1llu);
1677  std::shared_ptr<RenderPass> render_pass = spy->render_passes_[0];
1678  ASSERT_EQ(render_pass->GetCommands().size(), 2llu);
1679 }

References impeller::Color::CornflowerBlue(), impeller::Canvas::DrawRRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::kSource, impeller::kSourceOver, impeller::TRect< Scalar >::MakeXYWH(), impeller::Color::Red(), impeller::Picture::ToImage(), and impeller::Color::WithAlpha().

◆ TEST_P() [144/456]

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

Definition at line 320 of file aiks_path_unittests.cc.

320  {
321  Canvas canvas;
322  Paint paint;
323  paint.color = Color::Red();
324  paint.style = Paint::Style::kStroke;
325  paint.stroke_width = 10;
326 
327  canvas.Translate({100, 100});
328  canvas.DrawPath(
329  PathBuilder{}.AddRect(Rect::MakeSize(Size{100, 100})).TakePath(),
330  {paint});
331 
332  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
333 }

References impeller::PathBuilder::AddRect(), impeller::Canvas::DrawPath(), impeller::Canvas::EndRecordingAsPicture(), impeller::Paint::kStroke, impeller::TRect< Scalar >::MakeSize(), paint, impeller::Color::Red(), and impeller::Canvas::Translate().

◆ TEST_P() [145/456]

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

Definition at line 335 of file aiks_path_unittests.cc.

335  {
336  Canvas canvas;
337  Paint paint;
338  paint.color = Color::Red();
339  paint.style = Paint::Style::kStroke;
340  paint.stroke_width = 10;
341  paint.stroke_join = Join::kBevel;
342 
343  canvas.Translate({100, 100});
344  canvas.DrawPath(
345  PathBuilder{}.AddRect(Rect::MakeSize(Size{100, 100})).TakePath(),
346  {paint});
347 
348  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
349 }

References impeller::PathBuilder::AddRect(), impeller::Canvas::DrawPath(), impeller::Canvas::EndRecordingAsPicture(), impeller::kBevel, impeller::Paint::kStroke, impeller::TRect< Scalar >::MakeSize(), paint, impeller::Color::Red(), and impeller::Canvas::Translate().

◆ TEST_P() [146/456]

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

Definition at line 2401 of file aiks_unittests.cc.

2401  {
2402  Canvas canvas;
2403  canvas.Transform(Matrix(1.0, 0.0, 0.0, 0.0, //
2404  0.0, 1.0, 0.0, 0.0, //
2405  0.0, 0.0, 1.0, 0.01, //
2406  0.0, 0.0, 0.0, 1.0) * //
2407  Matrix::MakeRotationY({Degrees{10}}));
2408 
2409  ASSERT_TRUE(RenderTextInCanvasSkia(GetContext(), canvas, "Hello world",
2410  "Roboto-Regular.ttf"));
2411 
2412  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2413 }

References impeller::Canvas::EndRecordingAsPicture(), impeller::Matrix::MakeRotationY(), RenderTextInCanvasSkia(), and impeller::Canvas::Transform().

◆ TEST_P() [147/456]

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

Definition at line 2415 of file aiks_unittests.cc.

2415  {
2416  Canvas canvas;
2417  Paint save_paint;
2418  canvas.SaveLayer(save_paint);
2419  canvas.Transform(Matrix(1.0, 0.0, 0.0, 0.0, //
2420  0.0, 1.0, 0.0, 0.0, //
2421  0.0, 0.0, 1.0, 0.01, //
2422  0.0, 0.0, 0.0, 1.0) * //
2423  Matrix::MakeRotationY({Degrees{10}}));
2424 
2425  ASSERT_TRUE(RenderTextInCanvasSkia(GetContext(), canvas, "Hello world",
2426  "Roboto-Regular.ttf"));
2427  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2428 }

References impeller::Canvas::EndRecordingAsPicture(), impeller::Matrix::MakeRotationY(), RenderTextInCanvasSkia(), impeller::Canvas::SaveLayer(), and impeller::Canvas::Transform().

◆ TEST_P() [148/456]

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

Definition at line 259 of file aiks_dl_vertices_unittests.cc.

259  {
260  auto texture = CreateTextureForFixture("embarcadero.jpg");
261  auto dl_image = DlImageImpeller::Make(texture);
262  std::vector<SkPoint> positions = {SkPoint::Make(100, 300),
263  SkPoint::Make(200, 100),
264  SkPoint::Make(300, 300)};
265  std::vector<SkPoint> texture_coordinates = {
266  SkPoint::Make(0, 0), SkPoint::Make(100, 200), SkPoint::Make(200, 100)};
267 
268  auto vertices = flutter::DlVertices::Make(
269  flutter::DlVertexMode::kTriangles, 3, positions.data(),
270  texture_coordinates.data(), /*colors=*/nullptr);
271 
272  flutter::DisplayListBuilder builder;
273  flutter::DlPaint paint;
274 
275  auto image_source = flutter::DlImageColorSource(
276  dl_image, flutter::DlTileMode::kRepeat, flutter::DlTileMode::kRepeat);
277 
278  paint.setColorSource(&image_source);
279  builder.DrawVertices(vertices, flutter::DlBlendMode::kSrcOver, paint);
280 
281  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
282 }

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

◆ TEST_P() [149/456]

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

Definition at line 284 of file aiks_dl_vertices_unittests.cc.

285  {
286  auto texture = CreateTextureForFixture("embarcadero.jpg");
287  auto dl_image = DlImageImpeller::Make(texture);
288  std::vector<SkPoint> positions = {SkPoint::Make(100, 300),
289  SkPoint::Make(200, 100),
290  SkPoint::Make(300, 300)};
291  std::vector<flutter::DlColor> colors = {flutter::DlColor::kWhite(),
292  flutter::DlColor::kGreen(),
293  flutter::DlColor::kWhite()};
294  std::vector<SkPoint> texture_coordinates = {
295  SkPoint::Make(0, 0), SkPoint::Make(100, 200), SkPoint::Make(200, 100)};
296 
297  auto vertices = flutter::DlVertices::Make(
298  flutter::DlVertexMode::kTriangles, 3, positions.data(),
299  texture_coordinates.data(), colors.data());
300 
301  flutter::DisplayListBuilder builder;
302  flutter::DlPaint paint;
303 
304  auto image_source = flutter::DlImageColorSource(
305  dl_image, flutter::DlTileMode::kRepeat, flutter::DlTileMode::kRepeat);
306 
307  paint.setColorSource(&image_source);
308  builder.DrawVertices(vertices, flutter::DlBlendMode::kModulate, paint);
309 
310  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
311 }

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

◆ TEST_P() [150/456]

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

Definition at line 204 of file aiks_dl_vertices_unittests.cc.

204  {
205  std::vector<SkPoint> positions = {SkPoint::Make(100, 300),
206  SkPoint::Make(200, 100),
207  SkPoint::Make(300, 300)};
208 
209  auto vertices = flutter::DlVertices::Make(
210  flutter::DlVertexMode::kTriangles, 3, positions.data(),
211  /*texture_coordinates=*/nullptr, /*colors=*/nullptr);
212 
213  std::vector<flutter::DlColor> colors = {flutter::DlColor::kBlue(),
214  flutter::DlColor::kRed()};
215  const float stops[2] = {0.0, 1.0};
216 
217  auto linear = flutter::DlColorSource::MakeLinear(
218  {100.0, 100.0}, {300.0, 300.0}, 2, colors.data(), stops,
219  flutter::DlTileMode::kRepeat);
220 
221  flutter::DisplayListBuilder builder;
222  flutter::DlPaint paint;
223 
224  paint.setColorSource(linear);
225  builder.DrawVertices(vertices, flutter::DlBlendMode::kSrcOver, paint);
226 
227  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
228 }

References paint.

◆ TEST_P() [151/456]

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

Definition at line 230 of file aiks_dl_vertices_unittests.cc.

230  {
231  std::vector<SkPoint> positions = {SkPoint::Make(100, 300),
232  SkPoint::Make(200, 100),
233  SkPoint::Make(300, 300)};
234  std::vector<SkPoint> texture_coordinates = {SkPoint::Make(300, 100),
235  SkPoint::Make(100, 200),
236  SkPoint::Make(300, 300)};
237 
238  auto vertices = flutter::DlVertices::Make(
239  flutter::DlVertexMode::kTriangles, 3, positions.data(),
240  texture_coordinates.data(), /*colors=*/nullptr);
241 
242  std::vector<flutter::DlColor> colors = {flutter::DlColor::kBlue(),
243  flutter::DlColor::kRed()};
244  const float stops[2] = {0.0, 1.0};
245 
246  auto linear = flutter::DlColorSource::MakeLinear(
247  {100.0, 100.0}, {300.0, 300.0}, 2, colors.data(), stops,
248  flutter::DlTileMode::kRepeat);
249 
250  flutter::DisplayListBuilder builder;
251  flutter::DlPaint paint;
252 
253  paint.setColorSource(linear);
254  builder.DrawVertices(vertices, flutter::DlBlendMode::kSrcOver, paint);
255 
256  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
257 }

References paint.

◆ TEST_P() [152/456]

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

Definition at line 333 of file aiks_dl_vertices_unittests.cc.

333  {
334  std::vector<SkPoint> positions = {
335  SkPoint::Make(100, 300), SkPoint::Make(200, 100), SkPoint::Make(300, 300),
336  SkPoint::Make(200, 500)};
337  auto color = flutter::DlColor::kBlue().withAlpha(0x99);
338  std::vector<uint16_t> indices = {0, 1, 2, 0, 2, 3};
339  std::vector<flutter::DlColor> colors = {color, color, color, color};
340 
341  auto vertices = flutter::DlVertices::Make(
342  flutter::DlVertexMode::kTriangles, positions.size(), positions.data(),
343  /*texture_coordinates=*/nullptr, colors.data(), indices.size(),
344  indices.data());
345 
346  flutter::DisplayListBuilder builder;
347  flutter::DlPaint paint;
348  paint.setBlendMode(flutter::DlBlendMode::kSrcOver);
349  paint.setColor(flutter::DlColor::kRed());
350 
351  builder.DrawRect(SkRect::MakeLTRB(0, 0, 400, 400), paint);
352  builder.DrawVertices(vertices, flutter::DlBlendMode::kDst, paint);
353 
354  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
355 }

References color, and paint.

◆ TEST_P() [153/456]

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

Definition at line 313 of file aiks_dl_vertices_unittests.cc.

313  {
314  std::vector<SkPoint> positions = {
315  SkPoint::Make(100, 300), SkPoint::Make(200, 100), SkPoint::Make(300, 300),
316  SkPoint::Make(200, 500)};
317  std::vector<uint16_t> indices = {0, 1, 2, 0, 2, 3};
318 
319  auto vertices = flutter::DlVertices::Make(
320  flutter::DlVertexMode::kTriangles, positions.size(), positions.data(),
321  /*texture_coordinates=*/nullptr, /*colors=*/nullptr, indices.size(),
322  indices.data());
323 
324  flutter::DisplayListBuilder builder;
325  flutter::DlPaint paint;
326 
327  paint.setColor(flutter::DlColor::kRed());
328  builder.DrawVertices(vertices, flutter::DlBlendMode::kSrcOver, paint);
329 
330  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
331 }

References paint.

◆ TEST_P() [154/456]

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

Definition at line 180 of file aiks_dl_vertices_unittests.cc.

180  {
181  // Use negative coordinates and then scale the transform by -1, -1 to make
182  // sure coverage is taking the transform into account.
183  std::vector<SkPoint> positions = {SkPoint::Make(-100, -300),
184  SkPoint::Make(-200, -100),
185  SkPoint::Make(-300, -300)};
186  std::vector<flutter::DlColor> colors = {flutter::DlColor::kWhite(),
187  flutter::DlColor::kGreen(),
188  flutter::DlColor::kWhite()};
189 
190  auto vertices = flutter::DlVertices::Make(
191  flutter::DlVertexMode::kTriangles, 3, positions.data(),
192  /*texture_coordinates=*/nullptr, colors.data());
193 
194  flutter::DisplayListBuilder builder;
195  flutter::DlPaint paint;
196 
197  paint.setColor(flutter::DlColor::kRed().modulateOpacity(0.5));
198  builder.Scale(-1, -1);
199  builder.DrawVertices(vertices, flutter::DlBlendMode::kSrcOver, paint);
200 
201  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
202 }

References paint.

◆ TEST_P() [155/456]

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

Definition at line 359 of file aiks_dl_vertices_unittests.cc.

359  {
360  std::vector<SkPoint> positions_lt = {
361  SkPoint::Make(0, 0), //
362  SkPoint::Make(50, 0), //
363  SkPoint::Make(0, 50), //
364  SkPoint::Make(50, 50), //
365  };
366 
367  auto vertices_lt = flutter::DlVertices::Make(
368  flutter::DlVertexMode::kTriangleStrip, positions_lt.size(),
369  positions_lt.data(),
370  /*texture_coordinates=*/positions_lt.data(), /*colors=*/nullptr,
371  /*index_count=*/0,
372  /*indices=*/nullptr);
373 
374  std::vector<SkPoint> positions_rt = {
375  SkPoint::Make(50, 0), //
376  SkPoint::Make(100, 0), //
377  SkPoint::Make(50, 50), //
378  SkPoint::Make(100, 50), //
379  };
380 
381  auto vertices_rt = flutter::DlVertices::Make(
382  flutter::DlVertexMode::kTriangleStrip, positions_rt.size(),
383  positions_rt.data(),
384  /*texture_coordinates=*/positions_rt.data(), /*colors=*/nullptr,
385  /*index_count=*/0,
386  /*indices=*/nullptr);
387 
388  std::vector<SkPoint> positions_lb = {
389  SkPoint::Make(0, 50), //
390  SkPoint::Make(50, 50), //
391  SkPoint::Make(0, 100), //
392  SkPoint::Make(50, 100), //
393  };
394 
395  auto vertices_lb = flutter::DlVertices::Make(
396  flutter::DlVertexMode::kTriangleStrip, positions_lb.size(),
397  positions_lb.data(),
398  /*texture_coordinates=*/positions_lb.data(), /*colors=*/nullptr,
399  /*index_count=*/0,
400  /*indices=*/nullptr);
401 
402  std::vector<SkPoint> positions_rb = {
403  SkPoint::Make(50, 50), //
404  SkPoint::Make(100, 50), //
405  SkPoint::Make(50, 100), //
406  SkPoint::Make(100, 100), //
407  };
408 
409  auto vertices_rb = flutter::DlVertices::Make(
410  flutter::DlVertexMode::kTriangleStrip, positions_rb.size(),
411  positions_rb.data(),
412  /*texture_coordinates=*/positions_rb.data(), /*colors=*/nullptr,
413  /*index_count=*/0,
414  /*indices=*/nullptr);
415 
416  flutter::DisplayListBuilder builder;
417  flutter::DlPaint paint;
418  flutter::DlPaint rect_paint;
419  rect_paint.setColor(DlColor::kBlue());
420 
421  auto runtime_stages =
422  OpenAssetAsRuntimeStage("runtime_stage_simple.frag.iplr");
423 
424  auto runtime_stage =
425  runtime_stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
426  ASSERT_TRUE(runtime_stage);
427 
428  auto runtime_effect = DlRuntimeEffect::MakeImpeller(runtime_stage);
429  auto uniform_data = std::make_shared<std::vector<uint8_t>>();
430  auto color_source = flutter::DlColorSource::MakeRuntimeEffect(
431  runtime_effect, {}, uniform_data);
432 
433  paint.setColorSource(color_source);
434 
435  builder.Scale(GetContentScale().x, GetContentScale().y);
436  builder.Save();
437  builder.DrawRect(SkRect::MakeLTRB(0, 0, 100, 100), rect_paint);
438  builder.DrawVertices(vertices_lt, flutter::DlBlendMode::kSrcOver, paint);
439  builder.DrawVertices(vertices_rt, flutter::DlBlendMode::kSrcOver, paint);
440  builder.DrawVertices(vertices_lb, flutter::DlBlendMode::kSrcOver, paint);
441  builder.DrawVertices(vertices_rb, flutter::DlBlendMode::kSrcOver, paint);
442  builder.Restore();
443 
444  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
445 }

References paint, and impeller::PlaygroundBackendToRuntimeStageBackend().

◆ TEST_P() [156/456]

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

Definition at line 449 of file aiks_dl_vertices_unittests.cc.

450  {
451  std::vector<SkPoint> positions_lt = {
452  SkPoint::Make(200, 200), //
453  SkPoint::Make(250, 200), //
454  SkPoint::Make(200, 250), //
455  SkPoint::Make(250, 250), //
456  };
457 
458  auto vertices = flutter::DlVertices::Make(
459  flutter::DlVertexMode::kTriangleStrip, positions_lt.size(),
460  positions_lt.data(),
461  /*texture_coordinates=*/positions_lt.data(), /*colors=*/nullptr,
462  /*index_count=*/0,
463  /*indices=*/nullptr);
464 
465  flutter::DisplayListBuilder builder;
466  flutter::DlPaint paint;
467  flutter::DlPaint rect_paint;
468  rect_paint.setColor(DlColor::kBlue());
469 
470  auto runtime_stages =
471  OpenAssetAsRuntimeStage("runtime_stage_position.frag.iplr");
472 
473  auto runtime_stage =
474  runtime_stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
475  ASSERT_TRUE(runtime_stage);
476 
477  auto runtime_effect = DlRuntimeEffect::MakeImpeller(runtime_stage);
478  auto rect_data = std::vector<Rect>{Rect::MakeLTRB(200, 200, 250, 250)};
479 
480  auto uniform_data = std::make_shared<std::vector<uint8_t>>();
481  uniform_data->resize(rect_data.size() * sizeof(Rect));
482  memcpy(uniform_data->data(), rect_data.data(), uniform_data->size());
483 
484  auto color_source = flutter::DlColorSource::MakeRuntimeEffect(
485  runtime_effect, {}, uniform_data);
486 
487  paint.setColorSource(color_source);
488 
489  builder.Scale(GetContentScale().x, GetContentScale().y);
490  builder.DrawRect(SkRect::MakeLTRB(200, 200, 250, 250), rect_paint);
491  builder.DrawVertices(vertices, flutter::DlBlendMode::kSrcOver, paint);
492 
493  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
494 }

References impeller::TRect< Scalar >::MakeLTRB(), paint, and impeller::PlaygroundBackendToRuntimeStageBackend().

◆ TEST_P() [157/456]

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

Definition at line 2568 of file aiks_unittests.cc.

2568  {
2569  Canvas canvas;
2570  canvas.Scale(GetContentScale());
2571  canvas.DrawPaint(Paint{.color = Color::Red()});
2572  canvas.ClipRect(Rect::MakeXYWH(100, 100, 200, 200));
2573  canvas.SaveLayer(Paint{.color = Color::Blue()});
2574  canvas.Restore();
2575  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2576 }

References impeller::Color::Blue(), impeller::Canvas::ClipRect(), impeller::Paint::color, impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Color::Red(), impeller::Canvas::Restore(), impeller::Canvas::SaveLayer(), and impeller::Canvas::Scale().

◆ TEST_P() [158/456]

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

Definition at line 2578 of file aiks_unittests.cc.

2578  {
2579  Canvas canvas;
2580  canvas.Scale(GetContentScale());
2581  auto image = std::make_shared<Image>(CreateTextureForFixture("airplane.jpg"));
2582  canvas.DrawImage(image, {10, 10}, {});
2583  canvas.ClipRect(Rect::MakeXYWH(100, 100, 200, 200));
2584  canvas.SaveLayer(Paint{.blend_mode = BlendMode::kClear});
2585  canvas.Restore();
2586  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2587 }

References impeller::Paint::blend_mode, impeller::Canvas::ClipRect(), impeller::Canvas::DrawImage(), impeller::Canvas::EndRecordingAsPicture(), impeller::kClear, impeller::TRect< Scalar >::MakeXYWH(), impeller::Canvas::Restore(), impeller::Canvas::SaveLayer(), and impeller::Canvas::Scale().

◆ TEST_P() [159/456]

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

Definition at line 1261 of file aiks_unittests.cc.

1261  {
1262  Canvas canvas;
1263  canvas.Scale(GetContentScale());
1264  Paint paint;
1265  paint.mask_blur_descriptor = Paint::MaskBlurDescriptor{
1266  .style = FilterContents::BlurStyle::kNormal,
1267  .sigma = Sigma{1},
1268  };
1269 
1270  canvas.DrawPaint({.color = Color::White()});
1271 
1272  paint.color = Color::Blue();
1273  for (int i = 0; i < 5; i++) {
1274  Scalar y = i * 125;
1275  Scalar y_radius = i * 15;
1276  for (int j = 0; j < 5; j++) {
1277  Scalar x = j * 125;
1278  Scalar x_radius = j * 15;
1279  canvas.DrawRRect(Rect::MakeXYWH(x + 50, y + 50, 100.0f, 100.0f),
1280  {x_radius, y_radius}, paint);
1281  }
1282  }
1283 
1284  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1285 }

References impeller::Color::Blue(), impeller::Canvas::DrawPaint(), impeller::Canvas::DrawRRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::FilterContents::kNormal, impeller::TRect< Scalar >::MakeXYWH(), paint, impeller::Canvas::Scale(), impeller::Paint::MaskBlurDescriptor::style, and impeller::Color::White().

◆ TEST_P() [160/456]

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

Definition at line 716 of file aiks_dl_gradient_unittests.cc.

716  {
717  DisplayListBuilder builder;
718  DlPaint paint;
719  builder.Translate(100.0f, 0);
720 
721  std::vector<DlColor> colors = {DlColor::kRed(), DlColor::kBlue(),
722  DlColor::kGreen()};
723  std::vector<Scalar> stops = {0.0, 0.1, 1.0};
724 
725  paint.setColorSource(DlColorSource::MakeLinear({0, 0}, {300, 0}, stops.size(),
726  colors.data(), stops.data(),
727  DlTileMode::kClamp));
728 
729  paint.setColor(DlColor::kWhite());
730  builder.DrawRect(SkRect::MakeXYWH(0, 0, 300, 300), paint);
731  builder.Translate(400, 0);
732  builder.DrawRRect(SkRRect::MakeRectXY(SkRect::MakeXYWH(0, 0, 300, 300), 4, 4),
733  paint);
734 
735  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
736 }

References paint.

◆ TEST_P() [161/456]

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

Definition at line 762 of file aiks_dl_gradient_unittests.cc.

762  {
763  DisplayListBuilder builder;
764  DlPaint paint;
765  builder.Translate(100.0f, 0);
766 
767  std::vector<DlColor> colors = {DlColor::kRed(), DlColor::kBlue(),
768  DlColor::kGreen()};
769  std::vector<Scalar> stops = {0.0, 0.1, 1.0};
770 
771  paint.setColorSource(DlColorSource::MakeLinear({300, 0}, {0, 0}, stops.size(),
772  colors.data(), stops.data(),
773  DlTileMode::kClamp));
774 
775  paint.setColor(DlColor::kWhite());
776  builder.DrawRect(SkRect::MakeXYWH(0, 0, 300, 300), paint);
777  builder.Translate(400, 0);
778  builder.DrawRRect(SkRRect::MakeRectXY(SkRect::MakeXYWH(0, 0, 300, 300), 4, 4),
779  paint);
780 
781  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
782 }

References paint.

◆ TEST_P() [162/456]

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

Definition at line 739 of file aiks_dl_gradient_unittests.cc.

739  {
740  DisplayListBuilder builder;
741  DlPaint paint;
742  builder.Translate(100.0f, 0);
743 
744  std::vector<DlColor> colors = {DlColor::kRed(), DlColor::kBlue(),
745  DlColor::kGreen()};
746  std::vector<Scalar> stops = {0.0, 0.1, 1.0};
747 
748  paint.setColorSource(DlColorSource::MakeLinear({0, 0}, {0, 300}, stops.size(),
749  colors.data(), stops.data(),
750  DlTileMode::kClamp));
751 
752  paint.setColor(DlColor::kWhite());
753  builder.DrawRect(SkRect::MakeXYWH(0, 0, 300, 300), paint);
754  builder.Translate(400, 0);
755  builder.DrawRRect(SkRRect::MakeRectXY(SkRect::MakeXYWH(0, 0, 300, 300), 4, 4),
756  paint);
757 
758  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
759 }

References paint.

◆ TEST_P() [163/456]

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

Definition at line 785 of file aiks_dl_gradient_unittests.cc.

785  {
786  DisplayListBuilder builder;
787  DlPaint paint;
788  builder.Translate(100.0f, 0);
789 
790  std::vector<DlColor> colors = {DlColor::kRed(), DlColor::kBlue(),
791  DlColor::kGreen()};
792  std::vector<Scalar> stops = {0.0, 0.1, 1.0};
793 
794  paint.setColorSource(DlColorSource::MakeLinear({0, 300}, {0, 0}, stops.size(),
795  colors.data(), stops.data(),
796  DlTileMode::kClamp));
797 
798  paint.setColor(DlColor::kWhite());
799  builder.DrawRect(SkRect::MakeXYWH(0, 0, 300, 300), paint);
800  builder.Translate(400, 0);
801  builder.DrawRRect(SkRRect::MakeRectXY(SkRect::MakeXYWH(0, 0, 300, 300), 4, 4),
802  paint);
803 
804  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
805 }

References paint.

◆ TEST_P() [164/456]

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

Definition at line 923 of file aiks_unittests.cc.

923  {
924  Canvas canvas;
925  canvas.Scale(GetContentScale());
926  Paint paint;
927  const int color_count = 3;
928  Color colors[color_count] = {
929  Color::Blue(),
930  Color::Green(),
931  Color::Crimson(),
932  };
933 
934  paint.color = Color::White();
935  canvas.DrawPaint(paint);
936 
937  int c_index = 0;
938  int radius = 600;
939  while (radius > 0) {
940  paint.color = colors[(c_index++) % color_count];
941  canvas.DrawCircle({10, 10}, radius, paint);
942  if (radius > 30) {
943  radius -= 10;
944  } else {
945  radius -= 2;
946  }
947  }
948 
949  std::vector<Color> gradient_colors = {
950  Color{0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0},
951  Color{0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0},
952  Color{0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0},
953  Color{0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0},
954  Color{0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0},
955  Color{0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0},
956  Color{0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0}};
957  std::vector<Scalar> stops = {
958  0.0,
959  (1.0 / 6.0) * 1,
960  (1.0 / 6.0) * 2,
961  (1.0 / 6.0) * 3,
962  (1.0 / 6.0) * 4,
963  (1.0 / 6.0) * 5,
964  1.0,
965  };
966  auto texture = CreateTextureForFixture("airplane.jpg",
967  /*enable_mipmapping=*/true);
968 
969  paint.color_source = ColorSource::MakeRadialGradient(
970  {500, 600}, 75, std::move(gradient_colors), std::move(stops),
971  Entity::TileMode::kMirror, {});
972  canvas.DrawCircle({500, 600}, 100, paint);
973 
974  paint.color_source = ColorSource::MakeImage(
975  texture, Entity::TileMode::kRepeat, Entity::TileMode::kRepeat, {},
976  Matrix::MakeTranslation({700, 200}));
977  canvas.DrawCircle({800, 300}, 100, paint);
978 
979  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
980 }

References impeller::Color::Blue(), impeller::Color::Crimson(), impeller::Canvas::DrawCircle(), impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::Green(), impeller::Entity::kMirror, impeller::Entity::kRepeat, impeller::ColorSource::MakeImage(), impeller::ColorSource::MakeRadialGradient(), impeller::Matrix::MakeTranslation(), paint, impeller::Canvas::Scale(), and impeller::Color::White().

◆ TEST_P() [165/456]

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

Definition at line 1046 of file aiks_unittests.cc.

1046  {
1047  Canvas canvas;
1048  canvas.Scale(GetContentScale());
1049  Paint paint;
1050  const int color_count = 3;
1051  Color colors[color_count] = {
1052  Color::Blue(),
1053  Color::Green(),
1054  Color::Crimson(),
1055  };
1056 
1057  paint.color = Color::White();
1058  canvas.DrawPaint(paint);
1059 
1060  int c_index = 0;
1061  int long_radius = 600;
1062  int short_radius = 600;
1063  while (long_radius > 0 && short_radius > 0) {
1064  paint.color = colors[(c_index++) % color_count];
1065  canvas.DrawOval(Rect::MakeXYWH(10 - long_radius, 10 - short_radius,
1066  long_radius * 2, short_radius * 2),
1067  paint);
1068  canvas.DrawOval(Rect::MakeXYWH(1000 - short_radius, 750 - long_radius,
1069  short_radius * 2, long_radius * 2),
1070  paint);
1071  if (short_radius > 30) {
1072  short_radius -= 10;
1073  long_radius -= 5;
1074  } else {
1075  short_radius -= 2;
1076  long_radius -= 1;
1077  }
1078  }
1079 
1080  std::vector<Color> gradient_colors = {
1081  Color{0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0},
1082  Color{0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0},
1083  Color{0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0},
1084  Color{0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0},
1085  Color{0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0},
1086  Color{0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0},
1087  Color{0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0}};
1088  std::vector<Scalar> stops = {
1089  0.0,
1090  (1.0 / 6.0) * 1,
1091  (1.0 / 6.0) * 2,
1092  (1.0 / 6.0) * 3,
1093  (1.0 / 6.0) * 4,
1094  (1.0 / 6.0) * 5,
1095  1.0,
1096  };
1097  auto texture = CreateTextureForFixture("airplane.jpg",
1098  /*enable_mipmapping=*/true);
1099 
1100  paint.color = Color::White().WithAlpha(0.5);
1101 
1102  paint.color_source = ColorSource::MakeRadialGradient(
1103  {300, 650}, 75, std::move(gradient_colors), std::move(stops),
1104  Entity::TileMode::kMirror, {});
1105  canvas.DrawOval(Rect::MakeXYWH(200, 625, 200, 50), paint);
1106  canvas.DrawOval(Rect::MakeXYWH(275, 550, 50, 200), paint);
1107 
1108  paint.color_source = ColorSource::MakeImage(
1109  texture, Entity::TileMode::kRepeat, Entity::TileMode::kRepeat, {},
1110  Matrix::MakeTranslation({610, 15}));
1111  canvas.DrawOval(Rect::MakeXYWH(610, 90, 200, 50), paint);
1112  canvas.DrawOval(Rect::MakeXYWH(685, 15, 50, 200), paint);
1113 
1114  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1115 }

References impeller::Color::Blue(), impeller::Color::Crimson(), impeller::Canvas::DrawOval(), impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::Green(), impeller::Entity::kMirror, impeller::Entity::kRepeat, impeller::ColorSource::MakeImage(), impeller::ColorSource::MakeRadialGradient(), impeller::Matrix::MakeTranslation(), impeller::TRect< Scalar >::MakeXYWH(), paint, impeller::Canvas::Scale(), impeller::Color::White(), and impeller::Color::WithAlpha().

◆ TEST_P() [166/456]

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

Definition at line 1287 of file aiks_unittests.cc.

1287  {
1288  Canvas canvas;
1289  canvas.Scale(GetContentScale());
1290  Paint paint;
1291  const int color_count = 3;
1292  Color colors[color_count] = {
1293  Color::Blue(),
1294  Color::Green(),
1295  Color::Crimson(),
1296  };
1297 
1298  paint.color = Color::White();
1299  canvas.DrawPaint(paint);
1300 
1301  auto draw_rrect_as_path = [&canvas](const Rect& rect, const Size& radii,
1302  const Paint& paint) {
1303  PathBuilder builder = PathBuilder();
1304  builder.AddRoundedRect(rect, radii);
1305  canvas.DrawPath(builder.TakePath(), paint);
1306  };
1307 
1308  int c_index = 0;
1309  for (int i = 0; i < 4; i++) {
1310  for (int j = 0; j < 4; j++) {
1311  paint.color = colors[(c_index++) % color_count];
1312  draw_rrect_as_path(Rect::MakeXYWH(i * 100 + 10, j * 100 + 20, 80, 80),
1313  Size(i * 5 + 10, j * 5 + 10), paint);
1314  }
1315  }
1316  paint.color = colors[(c_index++) % color_count];
1317  draw_rrect_as_path(Rect::MakeXYWH(10, 420, 380, 80), Size(40, 40), paint);
1318  paint.color = colors[(c_index++) % color_count];
1319  draw_rrect_as_path(Rect::MakeXYWH(410, 20, 80, 380), Size(40, 40), paint);
1320 
1321  std::vector<Color> gradient_colors = {
1322  Color{0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0},
1323  Color{0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0},
1324  Color{0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0},
1325  Color{0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0},
1326  Color{0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0},
1327  Color{0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0},
1328  Color{0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0}};
1329  std::vector<Scalar> stops = {
1330  0.0,
1331  (1.0 / 6.0) * 1,
1332  (1.0 / 6.0) * 2,
1333  (1.0 / 6.0) * 3,
1334  (1.0 / 6.0) * 4,
1335  (1.0 / 6.0) * 5,
1336  1.0,
1337  };
1338  auto texture = CreateTextureForFixture("airplane.jpg",
1339  /*enable_mipmapping=*/true);
1340 
1341  paint.color = Color::White().WithAlpha(0.1);
1342  paint.color_source = ColorSource::MakeRadialGradient(
1343  {550, 550}, 75, gradient_colors, stops, Entity::TileMode::kMirror, {});
1344  for (int i = 1; i <= 10; i++) {
1345  int j = 11 - i;
1346  draw_rrect_as_path(Rect::MakeLTRB(550 - i * 20, 550 - j * 20, //
1347  550 + i * 20, 550 + j * 20),
1348  Size(i * 10, j * 10), paint);
1349  }
1350  paint.color = Color::White().WithAlpha(0.5);
1351  paint.color_source = ColorSource::MakeRadialGradient(
1352  {200, 650}, 75, std::move(gradient_colors), std::move(stops),
1353  Entity::TileMode::kMirror, {});
1354  draw_rrect_as_path(Rect::MakeLTRB(100, 610, 300, 690), Size(40, 40), paint);
1355  draw_rrect_as_path(Rect::MakeLTRB(160, 550, 240, 750), Size(40, 40), paint);
1356 
1357  paint.color = Color::White().WithAlpha(0.1);
1358  paint.color_source = ColorSource::MakeImage(
1359  texture, Entity::TileMode::kRepeat, Entity::TileMode::kRepeat, {},
1360  Matrix::MakeTranslation({520, 20}));
1361  for (int i = 1; i <= 10; i++) {
1362  int j = 11 - i;
1363  draw_rrect_as_path(Rect::MakeLTRB(720 - i * 20, 220 - j * 20, //
1364  720 + i * 20, 220 + j * 20),
1365  Size(i * 10, j * 10), paint);
1366  }
1367  paint.color = Color::White().WithAlpha(0.5);
1368  paint.color_source = ColorSource::MakeImage(
1369  texture, Entity::TileMode::kRepeat, Entity::TileMode::kRepeat, {},
1370  Matrix::MakeTranslation({800, 300}));
1371  draw_rrect_as_path(Rect::MakeLTRB(800, 410, 1000, 490), Size(40, 40), paint);
1372  draw_rrect_as_path(Rect::MakeLTRB(860, 350, 940, 550), Size(40, 40), paint);
1373 
1374  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1375 }

References impeller::PathBuilder::AddRoundedRect(), impeller::Color::Blue(), impeller::Color::Crimson(), impeller::Canvas::DrawPaint(), impeller::Canvas::DrawPath(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::Green(), impeller::Entity::kMirror, impeller::Entity::kRepeat, impeller::ColorSource::MakeImage(), impeller::TRect< Scalar >::MakeLTRB(), impeller::ColorSource::MakeRadialGradient(), impeller::Matrix::MakeTranslation(), impeller::TRect< Scalar >::MakeXYWH(), paint, impeller::Canvas::Scale(), impeller::PathBuilder::TakePath(), impeller::Color::White(), and impeller::Color::WithAlpha().

◆ TEST_P() [167/456]

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

Definition at line 1117 of file aiks_unittests.cc.

1117  {
1118  Canvas canvas;
1119  canvas.Scale(GetContentScale());
1120  Paint paint;
1121  const int color_count = 3;
1122  Color colors[color_count] = {
1123  Color::Blue(),
1124  Color::Green(),
1125  Color::Crimson(),
1126  };
1127 
1128  paint.color = Color::White();
1129  canvas.DrawPaint(paint);
1130 
1131  int c_index = 0;
1132  for (int i = 0; i < 4; i++) {
1133  for (int j = 0; j < 4; j++) {
1134  paint.color = colors[(c_index++) % color_count];
1135  canvas.DrawRRect(Rect::MakeXYWH(i * 100 + 10, j * 100 + 20, 80, 80),
1136  Size(i * 5 + 10, j * 5 + 10), paint);
1137  }
1138  }
1139  paint.color = colors[(c_index++) % color_count];
1140  canvas.DrawRRect(Rect::MakeXYWH(10, 420, 380, 80), Size(40, 40), paint);
1141  paint.color = colors[(c_index++) % color_count];
1142  canvas.DrawRRect(Rect::MakeXYWH(410, 20, 80, 380), Size(40, 40), paint);
1143 
1144  std::vector<Color> gradient_colors = {
1145  Color{0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0},
1146  Color{0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0},
1147  Color{0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0},
1148  Color{0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0},
1149  Color{0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0},
1150  Color{0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0},
1151  Color{0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0}};
1152  std::vector<Scalar> stops = {
1153  0.0,
1154  (1.0 / 6.0) * 1,
1155  (1.0 / 6.0) * 2,
1156  (1.0 / 6.0) * 3,
1157  (1.0 / 6.0) * 4,
1158  (1.0 / 6.0) * 5,
1159  1.0,
1160  };
1161  auto texture = CreateTextureForFixture("airplane.jpg",
1162  /*enable_mipmapping=*/true);
1163 
1164  paint.color = Color::White().WithAlpha(0.1);
1165  paint.color_source = ColorSource::MakeRadialGradient(
1166  {550, 550}, 75, gradient_colors, stops, Entity::TileMode::kMirror, {});
1167  for (int i = 1; i <= 10; i++) {
1168  int j = 11 - i;
1169  canvas.DrawRRect(Rect::MakeLTRB(550 - i * 20, 550 - j * 20, //
1170  550 + i * 20, 550 + j * 20),
1171  Size(i * 10, j * 10), paint);
1172  }
1173  paint.color = Color::White().WithAlpha(0.5);
1174  paint.color_source = ColorSource::MakeRadialGradient(
1175  {200, 650}, 75, std::move(gradient_colors), std::move(stops),
1176  Entity::TileMode::kMirror, {});
1177  canvas.DrawRRect(Rect::MakeLTRB(100, 610, 300, 690), Size(40, 40), paint);
1178  canvas.DrawRRect(Rect::MakeLTRB(160, 550, 240, 750), Size(40, 40), paint);
1179 
1180  paint.color = Color::White().WithAlpha(0.1);
1181  paint.color_source = ColorSource::MakeImage(
1182  texture, Entity::TileMode::kRepeat, Entity::TileMode::kRepeat, {},
1183  Matrix::MakeTranslation({520, 20}));
1184  for (int i = 1; i <= 10; i++) {
1185  int j = 11 - i;
1186  canvas.DrawRRect(Rect::MakeLTRB(720 - i * 20, 220 - j * 20, //
1187  720 + i * 20, 220 + j * 20),
1188  Size(i * 10, j * 10), paint);
1189  }
1190  paint.color = Color::White().WithAlpha(0.5);
1191  paint.color_source = ColorSource::MakeImage(
1192  texture, Entity::TileMode::kRepeat, Entity::TileMode::kRepeat, {},
1193  Matrix::MakeTranslation({800, 300}));
1194  canvas.DrawRRect(Rect::MakeLTRB(800, 410, 1000, 490), Size(40, 40), paint);
1195  canvas.DrawRRect(Rect::MakeLTRB(860, 350, 940, 550), Size(40, 40), paint);
1196 
1197  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1198 }

References impeller::Color::Blue(), impeller::Color::Crimson(), impeller::Canvas::DrawPaint(), impeller::Canvas::DrawRRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::Green(), impeller::Entity::kMirror, impeller::Entity::kRepeat, impeller::ColorSource::MakeImage(), impeller::TRect< Scalar >::MakeLTRB(), impeller::ColorSource::MakeRadialGradient(), impeller::Matrix::MakeTranslation(), impeller::TRect< Scalar >::MakeXYWH(), paint, impeller::Canvas::Scale(), impeller::Color::White(), and impeller::Color::WithAlpha().

◆ TEST_P() [168/456]

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

Definition at line 566 of file aiks_blend_unittests.cc.

566  {
567  auto texture = CreateTextureForFixture("airplane.jpg",
568  /*enable_mipmapping=*/true);
569 
570  Canvas canvas;
571  canvas.Rotate(Degrees(30));
572  canvas.DrawImage(std::make_shared<Image>(texture), {200, 200},
573  {.color_filter = ColorFilter::MakeBlend(
574  BlendMode::kColorDodge, Color::Orange())});
575 
576  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
577 }

References impeller::Canvas::DrawImage(), impeller::Canvas::EndRecordingAsPicture(), impeller::kColorDodge, impeller::ColorFilter::MakeBlend(), impeller::Color::Orange(), and impeller::Canvas::Rotate().

◆ TEST_P() [169/456]

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

Definition at line 341 of file aiks_blend_unittests.cc.

341  {
342  Canvas canvas;
343 
344  canvas.SaveLayer({
345  .color_filter =
346  ColorFilter::MakeBlend(BlendMode::kColorDodge, Color::Red()),
347  });
348 
349  canvas.Translate({500, 300, 0});
350  canvas.Rotate(Radians(2 * kPi / 3));
351  canvas.DrawRect(Rect::MakeXYWH(100, 100, 200, 200), {.color = Color::Blue()});
352 
353  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
354 }

References impeller::Color::Blue(), impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::kColorDodge, impeller::kPi, impeller::ColorFilter::MakeBlend(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Color::Red(), impeller::Canvas::Rotate(), impeller::Canvas::SaveLayer(), and impeller::Canvas::Translate().

◆ TEST_P() [170/456]

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

Definition at line 553 of file aiks_blend_unittests.cc.

553  {
554  auto texture = CreateTextureForFixture("airplane.jpg",
555  /*enable_mipmapping=*/true);
556 
557  Canvas canvas;
558  canvas.Rotate(Degrees(30));
559  canvas.DrawImage(std::make_shared<Image>(texture), {200, 200},
560  {.color_filter = ColorFilter::MakeBlend(BlendMode::kSourceIn,
561  Color::Orange())});
562 
563  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
564 }

References impeller::Canvas::DrawImage(), impeller::Canvas::EndRecordingAsPicture(), impeller::kSourceIn, impeller::ColorFilter::MakeBlend(), impeller::Color::Orange(), and impeller::Canvas::Rotate().

◆ TEST_P() [171/456]

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

Definition at line 876 of file aiks_unittests.cc.

876  {
877  PixelFormat pixel_format =
878  GetContext()->GetCapabilities()->GetDefaultColorFormat();
879  EXPECT_TRUE(pixel_format == PixelFormat::kR8G8B8A8UNormInt ||
880  pixel_format == PixelFormat::kB8G8R8A8UNormInt)
881  << "pixel format: " << PixelFormatToString(pixel_format);
882 }

References impeller::kB8G8R8A8UNormInt, impeller::kR8G8B8A8UNormInt, and impeller::PixelFormatToString().

◆ TEST_P() [172/456]

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

Definition at line 871 of file aiks_unittests.cc.

871  {
872  EXPECT_EQ(GetContext()->GetCapabilities()->GetDefaultColorFormat(),
873  PixelFormat::kB10G10R10A10XR);
874 }

References impeller::kB10G10R10A10XR.

◆ TEST_P() [173/456]

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

Definition at line 579 of file aiks_blend_unittests.cc.

579  {
580  auto texture = CreateTextureForFixture("airplane.jpg",
581  /*enable_mipmapping=*/true);
582 
583  // Draw with an advanced blend that can use FramebufferBlendContents and
584  // verify that the scale transform is correctly applied to the image.
585  Canvas canvas;
586  canvas.DrawPaint({.color = Color::DarkGray()});
587  canvas.Scale(Vector2(0.4, 0.4));
588  canvas.DrawImage(std::make_shared<Image>(texture), {20, 20},
589  {.blend_mode = BlendMode::kMultiply});
590 
591  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
592 }

References impeller::Color::DarkGray(), impeller::Canvas::DrawImage(), impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), impeller::kMultiply, and impeller::Canvas::Scale().

◆ TEST_P() [174/456]

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 122 of file aiks_dl_clip_unittests.cc.

122  {
123  DisplayListBuilder builder;
124 
125  // Clear the whole canvas with white.
126  DlPaint paint;
127  paint.setColor(DlColor::kWhite());
128  builder.DrawPaint(paint);
129 
130  builder.ClipPath(SkPath::Circle(150, 150, 50), DlCanvas::ClipOp::kIntersect);
131 
132  // Draw a red rectangle that should not show through the circle clip.
133  paint.setColor(DlColor::kRed());
134  paint.setBlendMode(DlBlendMode::kMultiply);
135  builder.DrawRect(SkRect::MakeXYWH(100, 100, 100, 100), paint);
136 
137  // Draw a green circle that shows through the clip.
138  paint.setColor(DlColor::kGreen());
139  paint.setBlendMode(DlBlendMode::kSrcOver);
140  builder.DrawCircle(SkPoint::Make(150, 150), 50, paint);
141 
142  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
143 }

References paint.

◆ TEST_P() [175/456]

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

Definition at line 1057 of file aiks_blur_unittests.cc.

1057  {
1058  size_t blur_required_mip_count =
1059  GetParam() == PlaygroundBackend::kOpenGLES ? 1 : 4;
1060 
1061  Canvas canvas;
1062  canvas.DrawCircle({100, 100}, 50, {.color = Color::CornflowerBlue()});
1063  canvas.SaveLayer({}, std::nullopt,
1064  ImageFilter::MakeBlur(Sigma(3), Sigma(3),
1065  FilterContents::BlurStyle::kNormal,
1066  Entity::TileMode::kClamp));
1067  canvas.Restore();
1068 
1069  Picture picture = canvas.EndRecordingAsPicture();
1070  std::shared_ptr<RenderTargetCache> cache =
1071  std::make_shared<RenderTargetCache>(GetContext()->GetResourceAllocator());
1072  AiksContext aiks_context(GetContext(), nullptr, cache);
1073  picture.ToImage(aiks_context, {100, 100});
1074 
1075  size_t max_mip_count = 0;
1076  for (auto it = cache->GetRenderTargetDataBegin();
1077  it != cache->GetRenderTargetDataEnd(); ++it) {
1078  max_mip_count = std::max(it->config.mip_count, max_mip_count);
1079  }
1080  EXPECT_EQ(max_mip_count, blur_required_mip_count);
1081 }

References impeller::Color::CornflowerBlue(), impeller::Canvas::DrawCircle(), impeller::Canvas::EndRecordingAsPicture(), impeller::Entity::kClamp, impeller::FilterContents::kNormal, impeller::kOpenGLES, impeller::ImageFilter::MakeBlur(), impeller::Canvas::Restore(), impeller::Canvas::SaveLayer(), and impeller::Picture::ToImage().

◆ TEST_P() [176/456]

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

Definition at line 763 of file aiks_blur_unittests.cc.

763  {
764  // This test is for checking out how stable rendering is when content is
765  // translated underneath a blur. Animating under a blur can cause
766  // *shimmering* to happen as a result of pixel alignment.
767  // See also: https://github.com/flutter/flutter/issues/140193
768  auto boston = std::make_shared<Image>(
769  CreateTextureForFixture("boston.jpg", /*enable_mipmapping=*/true));
770  ASSERT_TRUE(boston);
771  int64_t count = 0;
772  Scalar sigma = 20.0;
773  Scalar freq = 0.1;
774  Scalar amp = 50.0;
775  auto callback = [&](AiksContext& renderer) -> std::optional<Picture> {
776  if (AiksTest::ImGuiBegin("Controls", nullptr,
777  ImGuiWindowFlags_AlwaysAutoResize)) {
778  ImGui::SliderFloat("Sigma", &sigma, 0, 200);
779  ImGui::SliderFloat("Frequency", &freq, 0.01, 2.0);
780  ImGui::SliderFloat("Amplitude", &amp, 1, 100);
781  ImGui::End();
782  }
783 
784  Canvas canvas;
785  canvas.Scale(GetContentScale());
786  Scalar y = amp * sin(freq * 2.0 * M_PI * count / 60);
787  canvas.DrawImage(boston,
788  Point(1024 / 2 - boston->GetSize().width / 2,
789  (768 / 2 - boston->GetSize().height / 2) + y),
790  {});
791  static PlaygroundPoint point_a(Point(100, 100), 20, Color::Red());
792  static PlaygroundPoint point_b(Point(900, 700), 20, Color::Red());
793  auto [handle_a, handle_b] = DrawPlaygroundLine(point_a, point_b);
794  canvas.ClipRect(
795  Rect::MakeLTRB(handle_a.x, handle_a.y, handle_b.x, handle_b.y));
796  canvas.ClipRect(Rect::MakeLTRB(100, 100, 900, 700));
797  canvas.SaveLayer({.blend_mode = BlendMode::kSource}, std::nullopt,
798  ImageFilter::MakeBlur(Sigma(sigma), Sigma(sigma),
799  FilterContents::BlurStyle::kNormal,
800  Entity::TileMode::kClamp));
801  count += 1;
802  return canvas.EndRecordingAsPicture();
803  };
804  ASSERT_TRUE(OpenPlaygroundHere(callback));
805 }

References impeller::Canvas::ClipRect(), impeller::Canvas::DrawImage(), impeller::DrawPlaygroundLine(), impeller::Canvas::EndRecordingAsPicture(), impeller::AiksPlayground::ImGuiBegin(), impeller::Entity::kClamp, impeller::FilterContents::kNormal, impeller::kSource, impeller::ImageFilter::MakeBlur(), impeller::TRect< Scalar >::MakeLTRB(), impeller::Color::Red(), impeller::Canvas::SaveLayer(), and impeller::Canvas::Scale().

◆ TEST_P() [177/456]

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

Definition at line 479 of file aiks_blur_unittests.cc.

479  {
480  Canvas canvas;
481 
482  canvas.Scale(GetContentScale());
483  std::shared_ptr<Texture> boston = CreateTextureForFixture("boston.jpg");
484  canvas.DrawImageRect(
485  std::make_shared<Image>(boston),
486  Rect::MakeXYWH(0, 0, boston->GetSize().width, boston->GetSize().height),
487  Rect::MakeLTRB(0, 0, GetWindowSize().width, 100), Paint{});
488  canvas.DrawRRect(Rect::MakeLTRB(0, 110, GetWindowSize().width, 210),
489  Size(10, 10), Paint{.color = Color::Magenta()});
490  canvas.ClipRect(Rect::MakeLTRB(0, 50, GetWindowSize().width, 150));
491  canvas.SaveLayer({.blend_mode = BlendMode::kSource}, std::nullopt,
492  ImageFilter::MakeBlur(Sigma(20.0), Sigma(20.0),
493  FilterContents::BlurStyle::kNormal,
494  Entity::TileMode::kClamp));
495  canvas.Restore();
496  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
497 }

References impeller::Canvas::ClipRect(), impeller::Paint::color, impeller::Canvas::DrawImageRect(), impeller::Canvas::DrawRRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::Entity::kClamp, impeller::FilterContents::kNormal, impeller::kSource, impeller::Color::Magenta(), impeller::ImageFilter::MakeBlur(), impeller::TRect< Scalar >::MakeLTRB(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Canvas::Restore(), impeller::Canvas::SaveLayer(), and impeller::Canvas::Scale().

◆ TEST_P() [178/456]

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

Definition at line 461 of file aiks_blur_unittests.cc.

461  {
462  Canvas canvas;
463 
464  canvas.Scale(GetContentScale());
465  canvas.DrawRRect(Rect::MakeLTRB(0, 0, GetWindowSize().width, 100),
466  Size(10, 10), Paint{.color = Color::LimeGreen()});
467  canvas.DrawRRect(Rect::MakeLTRB(0, 110, GetWindowSize().width, 210),
468  Size(10, 10), Paint{.color = Color::Magenta()});
469  canvas.ClipRect(Rect::MakeLTRB(100, 0, 200, GetWindowSize().height));
470  canvas.SaveLayer({.blend_mode = BlendMode::kSource}, std::nullopt,
471  ImageFilter::MakeBlur(Sigma(20.0), Sigma(20.0),
472  FilterContents::BlurStyle::kNormal,
473  Entity::TileMode::kClamp));
474  canvas.Restore();
475 
476  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
477 }

References impeller::Canvas::ClipRect(), impeller::Paint::color, impeller::Canvas::DrawRRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::Entity::kClamp, impeller::FilterContents::kNormal, impeller::kSource, impeller::Color::LimeGreen(), impeller::Color::Magenta(), impeller::ImageFilter::MakeBlur(), impeller::TRect< Scalar >::MakeLTRB(), impeller::Canvas::Restore(), impeller::Canvas::SaveLayer(), and impeller::Canvas::Scale().

◆ TEST_P() [179/456]

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

Definition at line 737 of file aiks_blur_unittests.cc.

737  {
738  for (int32_t i = 0; i < 5; ++i) {
739  Canvas canvas;
740  ISize clip_size = ISize(i, i);
741  canvas.ClipRect(
742  Rect::MakeXYWH(400, 400, clip_size.width, clip_size.height));
743  canvas.DrawCircle(
744  {400, 400}, 200,
745  {
746  .color = Color::Green(),
747  .image_filter = ImageFilter::MakeBlur(
748  Sigma(0.1), Sigma(0.1), FilterContents::BlurStyle::kNormal,
749  Entity::TileMode::kDecal),
750  });
751  canvas.Restore();
752 
753  Picture picture = canvas.EndRecordingAsPicture();
754  std::shared_ptr<RenderTargetCache> cache =
755  std::make_shared<RenderTargetCache>(
756  GetContext()->GetResourceAllocator());
757  AiksContext aiks_context(GetContext(), nullptr, cache);
758  std::shared_ptr<Image> image = picture.ToImage(aiks_context, {1024, 768});
759  EXPECT_TRUE(image) << " clip rect " << i;
760  }
761 }

References impeller::Canvas::ClipRect(), impeller::Canvas::DrawCircle(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::Green(), impeller::TSize< T >::height, impeller::Entity::kDecal, impeller::FilterContents::kNormal, impeller::ImageFilter::MakeBlur(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Canvas::Restore(), impeller::Picture::ToImage(), and impeller::TSize< T >::width.

◆ TEST_P() [180/456]

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

Definition at line 1122 of file aiks_blur_unittests.cc.

1122  {
1123  size_t blur_required_mip_count =
1124  GetParam() == PlaygroundBackend::kOpenGLES ? 1 : 4;
1125  fml::testing::LogCapture log_capture;
1126  Canvas canvas;
1127  canvas.SaveLayer(
1128  {.image_filter = ImageFilter::MakeBlur(Sigma(30), Sigma(30),
1129  FilterContents::BlurStyle::kNormal,
1130  Entity::TileMode::kClamp)});
1131  canvas.DrawCircle({200, 200}, 50, {.color = Color::Chartreuse()});
1132 
1133  Picture picture = canvas.EndRecordingAsPicture();
1134  std::shared_ptr<RenderTargetCache> cache =
1135  std::make_shared<RenderTargetCache>(GetContext()->GetResourceAllocator());
1136  AiksContext aiks_context(GetContext(), nullptr, cache);
1137  picture.ToImage(aiks_context, {1024, 768});
1138 
1139  size_t max_mip_count = 0;
1140  for (auto it = cache->GetRenderTargetDataBegin();
1141  it != cache->GetRenderTargetDataEnd(); ++it) {
1142  max_mip_count = std::max(it->config.mip_count, max_mip_count);
1143  }
1144  EXPECT_EQ(max_mip_count, blur_required_mip_count);
1145  // The log is FML_DLOG, so only check in debug builds.
1146 #ifndef NDEBUG
1147  if (GetParam() != PlaygroundBackend::kOpenGLES) {
1148  EXPECT_EQ(log_capture.str().find(GaussianBlurFilterContents::kNoMipsError),
1149  std::string::npos);
1150  } else {
1151  EXPECT_NE(log_capture.str().find(GaussianBlurFilterContents::kNoMipsError),
1152  std::string::npos);
1153  }
1154 #endif
1155 }

References impeller::Color::Chartreuse(), impeller::Canvas::DrawCircle(), impeller::Canvas::EndRecordingAsPicture(), impeller::Entity::kClamp, impeller::GaussianBlurFilterContents::kNoMipsError, impeller::FilterContents::kNormal, impeller::kOpenGLES, impeller::ImageFilter::MakeBlur(), impeller::Canvas::SaveLayer(), and impeller::Picture::ToImage().

◆ TEST_P() [181/456]

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

Definition at line 1083 of file aiks_blur_unittests.cc.

1083  {
1084  fml::testing::LogCapture log_capture;
1085  size_t blur_required_mip_count =
1086  GetParam() == PlaygroundBackend::kOpenGLES ? 1 : 4;
1087 
1088  Canvas canvas;
1089  canvas.DrawPaint({.color = Color::Wheat()});
1090  canvas.SaveLayer({.blend_mode = BlendMode::kMultiply});
1091  canvas.DrawCircle({100, 100}, 50, {.color = Color::CornflowerBlue()});
1092  canvas.SaveLayer({}, std::nullopt,
1093  ImageFilter::MakeBlur(Sigma(30), Sigma(30),
1094  FilterContents::BlurStyle::kNormal,
1095  Entity::TileMode::kClamp));
1096  canvas.DrawCircle({200, 200}, 50, {.color = Color::Chartreuse()});
1097 
1098  Picture picture = canvas.EndRecordingAsPicture();
1099  std::shared_ptr<RenderTargetCache> cache =
1100  std::make_shared<RenderTargetCache>(GetContext()->GetResourceAllocator());
1101  AiksContext aiks_context(GetContext(), nullptr, cache);
1102  picture.ToImage(aiks_context, {100, 100});
1103 
1104  size_t max_mip_count = 0;
1105  for (auto it = cache->GetRenderTargetDataBegin();
1106  it != cache->GetRenderTargetDataEnd(); ++it) {
1107  max_mip_count = std::max(it->config.mip_count, max_mip_count);
1108  }
1109  EXPECT_EQ(max_mip_count, blur_required_mip_count);
1110  // The log is FML_DLOG, so only check in debug builds.
1111 #ifndef NDEBUG
1112  if (GetParam() != PlaygroundBackend::kOpenGLES) {
1113  EXPECT_EQ(log_capture.str().find(GaussianBlurFilterContents::kNoMipsError),
1114  std::string::npos);
1115  } else {
1116  EXPECT_NE(log_capture.str().find(GaussianBlurFilterContents::kNoMipsError),
1117  std::string::npos);
1118  }
1119 #endif
1120 }

References impeller::Color::Chartreuse(), impeller::Color::CornflowerBlue(), impeller::Canvas::DrawCircle(), impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), impeller::Entity::kClamp, impeller::kMultiply, impeller::GaussianBlurFilterContents::kNoMipsError, impeller::FilterContents::kNormal, impeller::kOpenGLES, impeller::ImageFilter::MakeBlur(), impeller::Canvas::SaveLayer(), impeller::Picture::ToImage(), and impeller::Color::Wheat().

◆ TEST_P() [182/456]

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

Definition at line 1157 of file aiks_blur_unittests.cc.

1157  {
1158  size_t blur_required_mip_count =
1159  GetParam() == PlaygroundBackend::kOpenGLES ? 1 : 4;
1160  fml::testing::LogCapture log_capture;
1161  Canvas canvas;
1162  canvas.DrawPath(PathBuilder{}
1163  .MoveTo({100, 100})
1164  .LineTo({200, 100})
1165  .LineTo({150, 200})
1166  .LineTo({50, 200})
1167  .Close()
1168  .TakePath(),
1169  {.color = Color::Chartreuse(),
1170  .image_filter = ImageFilter::MakeBlur(
1171  Sigma(30), Sigma(30), FilterContents::BlurStyle::kNormal,
1172  Entity::TileMode::kClamp)});
1173 
1174  Picture picture = canvas.EndRecordingAsPicture();
1175  std::shared_ptr<RenderTargetCache> cache =
1176  std::make_shared<RenderTargetCache>(GetContext()->GetResourceAllocator());
1177  AiksContext aiks_context(GetContext(), nullptr, cache);
1178  picture.ToImage(aiks_context, {1024, 768});
1179 
1180  size_t max_mip_count = 0;
1181  for (auto it = cache->GetRenderTargetDataBegin();
1182  it != cache->GetRenderTargetDataEnd(); ++it) {
1183  max_mip_count = std::max(it->config.mip_count, max_mip_count);
1184  }
1185  EXPECT_EQ(max_mip_count, blur_required_mip_count);
1186  // The log is FML_DLOG, so only check in debug builds.
1187 #ifndef NDEBUG
1188  if (GetParam() != PlaygroundBackend::kOpenGLES) {
1189  EXPECT_EQ(log_capture.str().find(GaussianBlurFilterContents::kNoMipsError),
1190  std::string::npos);
1191  } else {
1192  EXPECT_NE(log_capture.str().find(GaussianBlurFilterContents::kNoMipsError),
1193  std::string::npos);
1194  }
1195 #endif
1196 }

References impeller::Color::Chartreuse(), impeller::Close(), impeller::Canvas::DrawPath(), impeller::Canvas::EndRecordingAsPicture(), impeller::Entity::kClamp, impeller::GaussianBlurFilterContents::kNoMipsError, impeller::FilterContents::kNormal, impeller::kOpenGLES, impeller::LineTo(), impeller::ImageFilter::MakeBlur(), impeller::PathBuilder::MoveTo(), and impeller::Picture::ToImage().

◆ TEST_P() [183/456]

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

Definition at line 551 of file aiks_blur_unittests.cc.

551  {
552  Canvas canvas;
553 
554  canvas.Scale(GetContentScale());
555  canvas.Scale({0.5, 0.5, 1.0});
556  std::shared_ptr<Texture> boston = CreateTextureForFixture("boston.jpg");
557  canvas.DrawImage(std::make_shared<Image>(boston), Point(100, 100), Paint{});
558  canvas.SaveLayer({.blend_mode = BlendMode::kSource}, std::nullopt,
559  ImageFilter::MakeBlur(Sigma(50.0), Sigma(0.0),
560  FilterContents::BlurStyle::kNormal,
561  Entity::TileMode::kClamp));
562  canvas.Restore();
563  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
564 }

References impeller::Canvas::DrawImage(), impeller::Canvas::EndRecordingAsPicture(), impeller::Entity::kClamp, impeller::FilterContents::kNormal, impeller::kSource, impeller::ImageFilter::MakeBlur(), impeller::Canvas::Restore(), impeller::Canvas::SaveLayer(), and impeller::Canvas::Scale().

◆ TEST_P() [184/456]

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

Definition at line 570 of file aiks_blur_unittests.cc.

570  {
571  Canvas canvas;
572  std::shared_ptr<Texture> boston = CreateTextureForFixture("boston.jpg");
573  Rect bounds =
574  Rect::MakeXYWH(0, 0, boston->GetSize().width, boston->GetSize().height);
575  Vector2 image_center = Vector2(bounds.GetSize() / 2);
576  Paint paint = {.image_filter =
577  ImageFilter::MakeBlur(Sigma(20.0), Sigma(20.0),
578  FilterContents::BlurStyle::kNormal,
579  Entity::TileMode::kDecal)};
580  Vector2 clip_size = {150, 75};
581  Vector2 center = Vector2(1024, 768) / 2;
582  canvas.Scale(GetContentScale());
583  canvas.ClipRect(
584  Rect::MakeLTRB(center.x, center.y, center.x, center.y).Expand(clip_size));
585  canvas.Translate({center.x, center.y, 0});
586  canvas.Scale({0.6, 0.6, 1});
587  canvas.Rotate(Degrees(25));
588 
589  canvas.DrawImageRect(std::make_shared<Image>(boston), /*source=*/bounds,
590  /*dest=*/bounds.Shift(-image_center), paint);
591 
592  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
593 }

References impeller::Canvas::ClipRect(), impeller::Canvas::DrawImageRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::TRect< T >::Expand(), impeller::TRect< T >::GetSize(), impeller::Entity::kDecal, impeller::FilterContents::kNormal, impeller::ImageFilter::MakeBlur(), impeller::TRect< Scalar >::MakeLTRB(), impeller::TRect< Scalar >::MakeXYWH(), paint, impeller::Canvas::Rotate(), impeller::Canvas::Scale(), impeller::TRect< T >::Shift(), impeller::Canvas::Translate(), impeller::TPoint< T >::x, and impeller::TPoint< T >::y.

◆ TEST_P() [185/456]

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

Definition at line 619 of file aiks_blur_unittests.cc.

619  {
620  std::shared_ptr<Texture> boston = CreateTextureForFixture("boston.jpg");
621 
622  auto callback = [&](AiksContext& renderer) -> std::optional<Picture> {
623  const char* tile_mode_names[] = {"Clamp", "Repeat", "Mirror", "Decal"};
624  const Entity::TileMode tile_modes[] = {
625  Entity::TileMode::kClamp, Entity::TileMode::kRepeat,
626  Entity::TileMode::kMirror, Entity::TileMode::kDecal};
627 
628  static float rotation = 0;
629  static float scale = 0.6;
630  static int selected_tile_mode = 3;
631 
632  if (AiksTest::ImGuiBegin("Controls", nullptr,
633  ImGuiWindowFlags_AlwaysAutoResize)) {
634  ImGui::SliderFloat("Rotation (degrees)", &rotation, -180, 180);
635  ImGui::SliderFloat("Scale", &scale, 0, 2.0);
636  ImGui::Combo("Tile mode", &selected_tile_mode, tile_mode_names,
637  sizeof(tile_mode_names) / sizeof(char*));
638  ImGui::End();
639  }
640 
641  Canvas canvas;
642  Rect bounds =
643  Rect::MakeXYWH(0, 0, boston->GetSize().width, boston->GetSize().height);
644  Vector2 image_center = Vector2(bounds.GetSize() / 2);
645  Paint paint = {.image_filter =
646  ImageFilter::MakeBlur(Sigma(20.0), Sigma(20.0),
647  FilterContents::BlurStyle::kNormal,
648  tile_modes[selected_tile_mode])};
649  static PlaygroundPoint point_a(Point(362, 309), 20, Color::Red());
650  static PlaygroundPoint point_b(Point(662, 459), 20, Color::Red());
651  auto [handle_a, handle_b] = DrawPlaygroundLine(point_a, point_b);
652  Vector2 center = Vector2(1024, 768) / 2;
653  canvas.Scale(GetContentScale());
654  canvas.ClipRect(
655  Rect::MakeLTRB(handle_a.x, handle_a.y, handle_b.x, handle_b.y));
656  canvas.Translate({center.x, center.y, 0});
657  canvas.Scale({scale, scale, 1});
658  canvas.Rotate(Degrees(rotation));
659 
660  canvas.DrawImageRect(std::make_shared<Image>(boston), /*source=*/bounds,
661  /*dest=*/bounds.Shift(-image_center), paint);
662  return canvas.EndRecordingAsPicture();
663  };
664 
665  ASSERT_TRUE(OpenPlaygroundHere(callback));
666 }

References impeller::Canvas::ClipRect(), impeller::Canvas::DrawImageRect(), impeller::DrawPlaygroundLine(), impeller::Canvas::EndRecordingAsPicture(), impeller::TRect< T >::GetSize(), impeller::AiksPlayground::ImGuiBegin(), impeller::Entity::kClamp, impeller::Entity::kDecal, impeller::Entity::kMirror, impeller::FilterContents::kNormal, impeller::Entity::kRepeat, impeller::ImageFilter::MakeBlur(), impeller::TRect< Scalar >::MakeLTRB(), impeller::TRect< Scalar >::MakeXYWH(), paint, impeller::Color::Red(), impeller::Canvas::Rotate(), impeller::Canvas::Scale(), scale, impeller::TRect< T >::Shift(), impeller::Canvas::Translate(), impeller::TPoint< T >::x, and impeller::TPoint< T >::y.

◆ TEST_P() [186/456]

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

Definition at line 668 of file aiks_blur_unittests.cc.

668  {
669  auto callback = [&](AiksContext& renderer) -> std::optional<Picture> {
670  const char* tile_mode_names[] = {"Clamp", "Repeat", "Mirror", "Decal"};
671  const Entity::TileMode tile_modes[] = {
672  Entity::TileMode::kClamp, Entity::TileMode::kRepeat,
673  Entity::TileMode::kMirror, Entity::TileMode::kDecal};
674 
675  static float rotation = 45;
676  static float scale = 0.6;
677  static int selected_tile_mode = 3;
678 
679  if (AiksTest::ImGuiBegin("Controls", nullptr,
680  ImGuiWindowFlags_AlwaysAutoResize)) {
681  ImGui::SliderFloat("Rotation (degrees)", &rotation, -180, 180);
682  ImGui::SliderFloat("Scale", &scale, 0, 2.0);
683  ImGui::Combo("Tile mode", &selected_tile_mode, tile_mode_names,
684  sizeof(tile_mode_names) / sizeof(char*));
685  ImGui::End();
686  }
687 
688  Canvas canvas;
689  Paint paint = {.color = Color::Green(),
690  .image_filter =
691  ImageFilter::MakeBlur(Sigma(50.0), Sigma(0.0),
692  FilterContents::BlurStyle::kNormal,
693  tile_modes[selected_tile_mode])};
694  Vector2 center = Vector2(1024, 768) / 2;
695  canvas.Scale(GetContentScale());
696  canvas.Translate({center.x, center.y, 0});
697  canvas.Scale({scale, scale, 1});
698  canvas.Rotate(Degrees(rotation));
699 
700  canvas.DrawRRect(Rect::MakeXYWH(-100, -100, 200, 200), Size(10, 10), paint);
701  return canvas.EndRecordingAsPicture();
702  };
703 
704  ASSERT_TRUE(OpenPlaygroundHere(callback));
705 }

References impeller::Canvas::DrawRRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::Green(), impeller::AiksPlayground::ImGuiBegin(), impeller::Entity::kClamp, impeller::Entity::kDecal, impeller::Entity::kMirror, impeller::FilterContents::kNormal, impeller::Entity::kRepeat, impeller::ImageFilter::MakeBlur(), impeller::TRect< Scalar >::MakeXYWH(), paint, impeller::Canvas::Rotate(), impeller::Canvas::Scale(), scale, impeller::Canvas::Translate(), impeller::TPoint< T >::x, and impeller::TPoint< T >::y.

◆ TEST_P() [187/456]

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

Definition at line 595 of file aiks_blur_unittests.cc.

595  {
596  Canvas canvas;
597  std::shared_ptr<Texture> boston = CreateTextureForFixture("boston.jpg");
598  Rect bounds =
599  Rect::MakeXYWH(0, 0, boston->GetSize().width, boston->GetSize().height);
600  Vector2 image_center = Vector2(bounds.GetSize() / 2);
601  Paint paint = {.image_filter =
602  ImageFilter::MakeBlur(Sigma(20.0), Sigma(20.0),
603  FilterContents::BlurStyle::kNormal,
604  Entity::TileMode::kDecal)};
605  Vector2 clip_size = {150, 75};
606  Vector2 center = Vector2(1024, 768) / 2;
607  canvas.Scale(GetContentScale());
608  canvas.ClipRect(
609  Rect::MakeLTRB(center.x, center.y, center.x, center.y).Expand(clip_size));
610  canvas.Translate({center.x, center.y, 0});
611  canvas.Scale({0.6, 0.6, 1});
612 
613  canvas.DrawImageRect(std::make_shared<Image>(boston), /*source=*/bounds,
614  /*dest=*/bounds.Shift(-image_center), paint);
615 
616  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
617 }

References impeller::Canvas::ClipRect(), impeller::Canvas::DrawImageRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::TRect< T >::Expand(), impeller::TRect< T >::GetSize(), impeller::Entity::kDecal, impeller::FilterContents::kNormal, impeller::ImageFilter::MakeBlur(), impeller::TRect< Scalar >::MakeLTRB(), impeller::TRect< Scalar >::MakeXYWH(), paint, impeller::Canvas::Scale(), impeller::TRect< T >::Shift(), impeller::Canvas::Translate(), impeller::TPoint< T >::x, and impeller::TPoint< T >::y.

◆ TEST_P() [188/456]

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

Definition at line 1044 of file aiks_blur_unittests.cc.

1044  {
1045  Canvas canvas;
1046  canvas.DrawCircle({100, 100}, 50, {.color = Color::CornflowerBlue()});
1047  canvas.SaveLayer({}, std::nullopt,
1048  ImageFilter::MakeBlur(Sigma(3), Sigma(3),
1049  FilterContents::BlurStyle::kNormal,
1050  Entity::TileMode::kClamp));
1051  canvas.Restore();
1052 
1053  Picture picture = canvas.EndRecordingAsPicture();
1054  EXPECT_EQ(4, picture.pass->GetRequiredMipCount());
1055 }

References impeller::Color::CornflowerBlue(), impeller::Canvas::DrawCircle(), impeller::Canvas::EndRecordingAsPicture(), impeller::Entity::kClamp, impeller::FilterContents::kNormal, impeller::ImageFilter::MakeBlur(), impeller::Picture::pass, impeller::Canvas::Restore(), and impeller::Canvas::SaveLayer().

◆ TEST_P() [189/456]

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

Definition at line 710 of file aiks_blur_unittests.cc.

710  {
711  for (int32_t i = 1; i < 5; ++i) {
712  Canvas canvas;
713  Scalar fi = i;
714  canvas.DrawPath(
715  PathBuilder{}
716  .MoveTo({100, 100})
717  .LineTo({100.f + fi, 100.f + fi})
718  .TakePath(),
719  {.color = Color::Chartreuse(),
720  .image_filter = ImageFilter::MakeBlur(
721  Sigma(0.1), Sigma(0.1), FilterContents::BlurStyle::kNormal,
722  Entity::TileMode::kClamp)});
723 
724  Picture picture = canvas.EndRecordingAsPicture();
725  std::shared_ptr<RenderTargetCache> cache =
726  std::make_shared<RenderTargetCache>(
727  GetContext()->GetResourceAllocator());
728  AiksContext aiks_context(GetContext(), nullptr, cache);
729  std::shared_ptr<Image> image = picture.ToImage(aiks_context, {1024, 768});
730  EXPECT_TRUE(image) << " length " << i;
731  }
732 }

References impeller::Color::Chartreuse(), impeller::Canvas::DrawPath(), impeller::Canvas::EndRecordingAsPicture(), impeller::Entity::kClamp, impeller::FilterContents::kNormal, impeller::LineTo(), impeller::ImageFilter::MakeBlur(), impeller::PathBuilder::MoveTo(), and impeller::Picture::ToImage().

◆ TEST_P() [190/456]

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

Definition at line 906 of file aiks_blur_unittests.cc.

906  {
907  Canvas canvas;
908  canvas.Scale(GetContentScale());
909 
910  canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)});
911 
912  Paint paint;
913  paint.color = Color::Green();
914  paint.mask_blur_descriptor = Paint::MaskBlurDescriptor{
915  .style = FilterContents::BlurStyle::kInner,
916  .sigma = Sigma(30),
917  };
918  canvas.DrawPath(PathBuilder()
919  .MoveTo({200, 200})
920  .LineTo({300, 400})
921  .LineTo({100, 400})
922  .Close()
923  .TakePath(),
924  paint);
925 
926  // Draw another thing to make sure the clip area is reset.
927  Paint red;
928  red.color = Color::Red();
929  canvas.DrawRect(Rect::MakeXYWH(0, 0, 200, 200), red);
930 
931  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
932 }

References impeller::Close(), impeller::Paint::color, impeller::Canvas::DrawPaint(), impeller::Canvas::DrawPath(), impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::Green(), impeller::FilterContents::kInner, impeller::LineTo(), impeller::TRect< Scalar >::MakeXYWH(), impeller::MoveTo(), paint, impeller::Color::Red(), impeller::Canvas::Scale(), and impeller::Paint::MaskBlurDescriptor::style.

◆ TEST_P() [191/456]

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

Definition at line 807 of file aiks_blur_unittests.cc.

807  {
808  Canvas canvas;
809  canvas.Scale(GetContentScale());
810 
811  canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)});
812 
813  std::vector<Color> colors = {Color{0.9568, 0.2627, 0.2118, 1.0},
814  Color{0.7568, 0.2627, 0.2118, 1.0}};
815  std::vector<Scalar> stops = {0.0, 1.0};
816 
817  Paint paint;
818  paint.color_source = ColorSource::MakeLinearGradient(
819  {0, 0}, {200, 200}, std::move(colors), std::move(stops),
820  Entity::TileMode::kMirror, {});
821  paint.mask_blur_descriptor = Paint::MaskBlurDescriptor{
822  .style = FilterContents::BlurStyle::kInner,
823  .sigma = Sigma(30),
824  };
825  canvas.DrawPath(PathBuilder()
826  .MoveTo({200, 200})
827  .LineTo({300, 400})
828  .LineTo({100, 400})
829  .Close()
830  .TakePath(),
831  paint);
832 
833  // Draw another thing to make sure the clip area is reset.
834  Paint red;
835  red.color = Color::Red();
836  canvas.DrawRect(Rect::MakeXYWH(0, 0, 200, 200), red);
837  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
838 }

References impeller::Close(), impeller::Paint::color, impeller::Canvas::DrawPaint(), impeller::Canvas::DrawPath(), impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::FilterContents::kInner, impeller::Entity::kMirror, impeller::LineTo(), impeller::ColorSource::MakeLinearGradient(), impeller::TRect< Scalar >::MakeXYWH(), impeller::MoveTo(), paint, impeller::Color::Red(), impeller::Canvas::Scale(), and impeller::Paint::MaskBlurDescriptor::style.

◆ TEST_P() [192/456]

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

Definition at line 934 of file aiks_blur_unittests.cc.

934  {
935  Canvas canvas;
936  canvas.Scale(GetContentScale());
937 
938  canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)});
939 
940  Paint paint;
941  paint.color = Color::Green();
942  paint.mask_blur_descriptor = Paint::MaskBlurDescriptor{
943  .style = FilterContents::BlurStyle::kOuter,
944  .sigma = Sigma(30),
945  };
946  canvas.DrawPath(PathBuilder()
947  .MoveTo({200, 200})
948  .LineTo({300, 400})
949  .LineTo({100, 400})
950  .Close()
951  .TakePath(),
952  paint);
953 
954  // Draw another thing to make sure the clip area is reset.
955  Paint red;
956  red.color = Color::Red();
957  canvas.DrawRect(Rect::MakeXYWH(0, 0, 200, 200), red);
958 
959  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
960 }

References impeller::Close(), impeller::Paint::color, impeller::Canvas::DrawPaint(), impeller::Canvas::DrawPath(), impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::Green(), impeller::FilterContents::kOuter, impeller::LineTo(), impeller::TRect< Scalar >::MakeXYWH(), impeller::MoveTo(), paint, impeller::Color::Red(), impeller::Canvas::Scale(), and impeller::Paint::MaskBlurDescriptor::style.

◆ TEST_P() [193/456]

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

Definition at line 873 of file aiks_blur_unittests.cc.

873  {
874  Canvas canvas;
875  canvas.Scale(GetContentScale());
876 
877  canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)});
878 
879  std::vector<Color> colors = {Color{0.9568, 0.2627, 0.2118, 1.0},
880  Color{0.7568, 0.2627, 0.2118, 1.0}};
881  std::vector<Scalar> stops = {0.0, 1.0};
882 
883  Paint paint;
884  paint.color_source = ColorSource::MakeLinearGradient(
885  {0, 0}, {200, 200}, std::move(colors), std::move(stops),
886  Entity::TileMode::kMirror, {});
887  paint.mask_blur_descriptor = Paint::MaskBlurDescriptor{
888  .style = FilterContents::BlurStyle::kOuter,
889  .sigma = Sigma(30),
890  };
891  canvas.DrawPath(PathBuilder()
892  .MoveTo({200, 200})
893  .LineTo({300, 400})
894  .LineTo({100, 400})
895  .Close()
896  .TakePath(),
897  paint);
898 
899  // Draw another thing to make sure the clip area is reset.
900  Paint red;
901  red.color = Color::Red();
902  canvas.DrawRect(Rect::MakeXYWH(0, 0, 200, 200), red);
903  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
904 }

References impeller::Close(), impeller::Paint::color, impeller::Canvas::DrawPaint(), impeller::Canvas::DrawPath(), impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::Entity::kMirror, impeller::FilterContents::kOuter, impeller::LineTo(), impeller::ColorSource::MakeLinearGradient(), impeller::TRect< Scalar >::MakeXYWH(), impeller::MoveTo(), paint, impeller::Color::Red(), impeller::Canvas::Scale(), and impeller::Paint::MaskBlurDescriptor::style.

◆ TEST_P() [194/456]

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

Definition at line 962 of file aiks_blur_unittests.cc.

962  {
963  Canvas canvas;
964  canvas.Scale(GetContentScale());
965 
966  canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)});
967 
968  Paint paint;
969  paint.color = Color::Green();
970  paint.mask_blur_descriptor = Paint::MaskBlurDescriptor{
971  .style = FilterContents::BlurStyle::kSolid,
972  .sigma = Sigma(30),
973  };
974  canvas.DrawPath(PathBuilder()
975  .MoveTo({200, 200})
976  .LineTo({300, 400})
977  .LineTo({100, 400})
978  .Close()
979  .TakePath(),
980  paint);
981 
982  // Draw another thing to make sure the clip area is reset.
983  Paint red;
984  red.color = Color::Red();
985  canvas.DrawRect(Rect::MakeXYWH(0, 0, 200, 200), red);
986 
987  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
988 }

References impeller::Close(), impeller::Paint::color, impeller::Canvas::DrawPaint(), impeller::Canvas::DrawPath(), impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::Green(), impeller::FilterContents::kSolid, impeller::LineTo(), impeller::TRect< Scalar >::MakeXYWH(), impeller::MoveTo(), paint, impeller::Color::Red(), impeller::Canvas::Scale(), and impeller::Paint::MaskBlurDescriptor::style.

◆ TEST_P() [195/456]

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

Definition at line 840 of file aiks_blur_unittests.cc.

840  {
841  Canvas canvas;
842  canvas.Scale(GetContentScale());
843 
844  canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)});
845 
846  std::vector<Color> colors = {Color{0.9568, 0.2627, 0.2118, 1.0},
847  Color{0.7568, 0.2627, 0.2118, 1.0}};
848  std::vector<Scalar> stops = {0.0, 1.0};
849 
850  Paint paint;
851  paint.color_source = ColorSource::MakeLinearGradient(
852  {0, 0}, {200, 200}, std::move(colors), std::move(stops),
853  Entity::TileMode::kMirror, {});
854  paint.mask_blur_descriptor = Paint::MaskBlurDescriptor{
855  .style = FilterContents::BlurStyle::kSolid,
856  .sigma = Sigma(30),
857  };
858  canvas.DrawPath(PathBuilder()
859  .MoveTo({200, 200})
860  .LineTo({300, 400})
861  .LineTo({100, 400})
862  .Close()
863  .TakePath(),
864  paint);
865 
866  // Draw another thing to make sure the clip area is reset.
867  Paint red;
868  red.color = Color::Red();
869  canvas.DrawRect(Rect::MakeXYWH(0, 0, 200, 200), red);
870  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
871 }

References impeller::Close(), impeller::Paint::color, impeller::Canvas::DrawPaint(), impeller::Canvas::DrawPath(), impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::Entity::kMirror, impeller::FilterContents::kSolid, impeller::LineTo(), impeller::ColorSource::MakeLinearGradient(), impeller::TRect< Scalar >::MakeXYWH(), impeller::MoveTo(), paint, impeller::Color::Red(), impeller::Canvas::Scale(), and impeller::Paint::MaskBlurDescriptor::style.

◆ TEST_P() [196/456]

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

Definition at line 503 of file aiks_blur_unittests.cc.

503  {
504  if (GetParam() != PlaygroundBackend::kMetal) {
505  GTEST_SKIP_(
506  "This backend doesn't yet support setting device capabilities.");
507  }
508  if (!WillRenderSomething()) {
509  // Sometimes these tests are run without playgrounds enabled which is
510  // pointless for this test since we are asserting that
511  // `SupportsDecalSamplerAddressMode` is called.
512  GTEST_SKIP_("This test requires playgrounds.");
513  }
514 
515  std::shared_ptr<const Capabilities> old_capabilities =
516  GetContext()->GetCapabilities();
517  auto mock_capabilities = std::make_shared<MockCapabilities>();
518  EXPECT_CALL(*mock_capabilities, SupportsDecalSamplerAddressMode())
519  .Times(::testing::AtLeast(1))
520  .WillRepeatedly(::testing::Return(false));
521  FLT_FORWARD(mock_capabilities, old_capabilities, GetDefaultColorFormat);
522  FLT_FORWARD(mock_capabilities, old_capabilities, GetDefaultStencilFormat);
523  FLT_FORWARD(mock_capabilities, old_capabilities,
524  GetDefaultDepthStencilFormat);
525  FLT_FORWARD(mock_capabilities, old_capabilities, SupportsOffscreenMSAA);
526  FLT_FORWARD(mock_capabilities, old_capabilities,
527  SupportsImplicitResolvingMSAA);
528  FLT_FORWARD(mock_capabilities, old_capabilities, SupportsReadFromResolve);
529  FLT_FORWARD(mock_capabilities, old_capabilities, SupportsFramebufferFetch);
530  FLT_FORWARD(mock_capabilities, old_capabilities, SupportsSSBO);
531  FLT_FORWARD(mock_capabilities, old_capabilities, SupportsCompute);
532  FLT_FORWARD(mock_capabilities, old_capabilities,
533  SupportsTextureToTextureBlits);
534  FLT_FORWARD(mock_capabilities, old_capabilities, GetDefaultGlyphAtlasFormat);
535  ASSERT_TRUE(SetCapabilities(mock_capabilities).ok());
536 
537  auto texture = std::make_shared<Image>(CreateTextureForFixture("boston.jpg"));
538  Canvas canvas;
539  canvas.Scale(GetContentScale() * 0.5);
540  canvas.DrawPaint({.color = Color::Black()});
541  canvas.DrawImage(
542  texture, Point(200, 200),
543  {
544  .image_filter = ImageFilter::MakeBlur(
545  Sigma(20.0), Sigma(20.0), FilterContents::BlurStyle::kNormal,
546  Entity::TileMode::kDecal),
547  });
548  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
549 }

References impeller::Color::Black(), impeller::Canvas::DrawImage(), impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), FLT_FORWARD, impeller::Entity::kDecal, impeller::kMetal, impeller::FilterContents::kNormal, impeller::ImageFilter::MakeBlur(), and impeller::Canvas::Scale().

◆ TEST_P() [197/456]

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

Definition at line 624 of file aiks_dl_gradient_unittests.cc.

624  {
625  // Compare with https://fiddle.skia.org/c/027392122bec8ac2b5d5de00a4b9bbe2
626  auto callback = [&]() -> sk_sp<DisplayList> {
627  static float scale = 3;
628  static bool add_circle_clip = true;
629  const char* tile_mode_names[] = {"Clamp", "Repeat", "Mirror", "Decal"};
630  const DlTileMode tile_modes[] = {DlTileMode::kClamp, DlTileMode::kRepeat,
631  DlTileMode::kMirror, DlTileMode::kDecal};
632  static int selected_tile_mode = 0;
633  static float alpha = 1;
634 
635  if (AiksTest::ImGuiBegin("Controls", nullptr,
636  ImGuiWindowFlags_AlwaysAutoResize)) {
637  ImGui::SliderFloat("Scale", &scale, 0, 6);
638  ImGui::Checkbox("Circle clip", &add_circle_clip);
639  ImGui::SliderFloat("Alpha", &alpha, 0, 1);
640  ImGui::Combo("Tile mode", &selected_tile_mode, tile_mode_names,
641  sizeof(tile_mode_names) / sizeof(char*));
642  ImGui::End();
643  }
644 
645  DisplayListBuilder builder;
646  builder.Scale(GetContentScale().x, GetContentScale().y);
647  DlPaint paint;
648  paint.setColor(DlColor::kWhite());
649  builder.DrawPaint(paint);
650 
651  paint.setDrawStyle(DlDrawStyle::kStroke);
652  paint.setColor(DlColor::kWhite().withAlpha(alpha * 255));
653  paint.setStrokeWidth(10);
654  auto tile_mode = tile_modes[selected_tile_mode];
655 
656  std::vector<DlColor> colors = {
657  DlColor(Color{0.9568, 0.2627, 0.2118, 1.0}.ToARGB()),
658  DlColor(Color{0.1294, 0.5882, 0.9529, 1.0}.ToARGB())};
659  std::vector<Scalar> stops = {0.0, 1.0};
660 
661  paint.setColorSource(DlColorSource::MakeLinear({0, 0}, {50, 50},
662  stops.size(), colors.data(),
663  stops.data(), tile_mode));
664 
665  SkPath path;
666  path.moveTo(20, 20);
667  path.quadTo({60, 20}, {60, 60});
668  path.close();
669  path.moveTo(60, 20);
670  path.quadTo({60, 60}, {20, 60});
671 
672  builder.Scale(scale, scale);
673 
674  if (add_circle_clip) {
675  static PlaygroundPoint circle_clip_point_a(Point(60, 300), 20,
676  Color::Red());
677  static PlaygroundPoint circle_clip_point_b(Point(600, 300), 20,
678  Color::Red());
679  auto [handle_a, handle_b] =
680  DrawPlaygroundLine(circle_clip_point_a, circle_clip_point_b);
681 
682  SkMatrix screen_to_canvas;
683  if (!builder.GetTransform().invert(&screen_to_canvas)) {
684  return nullptr;
685  }
686  Matrix ip_matrix = ToMatrix(screen_to_canvas);
687  Point point_a = ip_matrix * handle_a * GetContentScale();
688  Point point_b = ip_matrix * handle_b * GetContentScale();
689 
690  Point middle = (point_a + point_b) / 2;
691  auto radius = point_a.GetDistance(middle);
692  SkPath circle;
693  circle.addCircle(middle.x, middle.y, radius);
694  builder.ClipPath(circle);
695  }
696 
697  for (auto join :
698  {DlStrokeJoin::kBevel, DlStrokeJoin::kRound, DlStrokeJoin::kMiter}) {
699  paint.setStrokeJoin(join);
700  for (auto cap :
701  {DlStrokeCap::kButt, DlStrokeCap::kSquare, DlStrokeCap::kRound}) {
702  paint.setStrokeCap(cap);
703  builder.DrawPath(path, paint);
704  builder.Translate(80, 0);
705  }
706  builder.Translate(-240, 60);
707  }
708 
709  return builder.Build();
710  };
711 
712  ASSERT_TRUE(OpenPlaygroundHere(callback));
713 }

References impeller::DrawPlaygroundLine(), impeller::TPoint< T >::GetDistance(), paint, scale, impeller::Color::ToARGB(), impeller::ToMatrix(), impeller::TPoint< T >::x, and impeller::TPoint< T >::y.

◆ TEST_P() [198/456]

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

Definition at line 1016 of file aiks_blur_unittests.cc.

1016  {
1017  // This makes sure if mip maps are recycled across invocations of blurs the
1018  // contents get updated each frame correctly. If they aren't updated the color
1019  // inside the blur and outside the blur will be different.
1020  //
1021  // If there is some change to render target caching this could display a false
1022  // positive in the future. Also, if the LOD that is rendered is 1 it could
1023  // present a false positive.
1024  int32_t count = 0;
1025  auto callback = [&](AiksContext& renderer) -> std::optional<Picture> {
1026  Canvas canvas;
1027  if (count++ == 0) {
1028  canvas.DrawCircle({100, 100}, 50, {.color = Color::CornflowerBlue()});
1029  } else {
1030  canvas.DrawCircle({100, 100}, 50, {.color = Color::Chartreuse()});
1031  }
1032  canvas.ClipRRect(Rect::MakeLTRB(75, 50, 375, 275), {20, 20});
1033  canvas.SaveLayer({.blend_mode = BlendMode::kSource}, std::nullopt,
1034  ImageFilter::MakeBlur(Sigma(30.0), Sigma(30.0),
1035  FilterContents::BlurStyle::kNormal,
1036  Entity::TileMode::kClamp));
1037  canvas.Restore();
1038  return canvas.EndRecordingAsPicture();
1039  };
1040 
1041  ASSERT_TRUE(OpenPlaygroundHere(callback));
1042 }

References impeller::Color::Chartreuse(), impeller::Canvas::ClipRRect(), impeller::Color::CornflowerBlue(), impeller::Canvas::DrawCircle(), impeller::Canvas::EndRecordingAsPicture(), impeller::Entity::kClamp, impeller::FilterContents::kNormal, impeller::kSource, impeller::ImageFilter::MakeBlur(), impeller::TRect< Scalar >::MakeLTRB(), impeller::Canvas::Restore(), and impeller::Canvas::SaveLayer().

◆ TEST_P() [199/456]

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

Definition at line 2611 of file aiks_unittests.cc.

2611  {
2612  // Compare with https://fiddle.skia.org/c/6cdc5aefb291fda3833b806ca347a885
2613 
2614  Canvas canvas;
2615  auto texture = CreateTextureForFixture("monkey.png");
2616 
2617  canvas.DrawPaint({.color = Color::White()});
2618 
2619  // Translation
2620  {
2621  Paint paint;
2622  paint.color_source = ColorSource::MakeImage(
2623  texture, Entity::TileMode::kRepeat, Entity::TileMode::kRepeat, {},
2624  Matrix::MakeTranslation({50, 50}));
2625  canvas.DrawRect(Rect::MakeLTRB(0, 0, 100, 100), paint);
2626  }
2627 
2628  // Rotation/skew
2629  {
2630  canvas.Save();
2631  canvas.Rotate(Degrees(45));
2632  Paint paint;
2633  paint.color_source = ColorSource::MakeImage(
2634  texture, Entity::TileMode::kRepeat, Entity::TileMode::kRepeat, {},
2635  Matrix(1, -1, 0, 0, //
2636  1, 1, 0, 0, //
2637  0, 0, 1, 0, //
2638  0, 0, 0, 1) //
2639  );
2640  canvas.DrawRect(Rect::MakeLTRB(100, 0, 200, 100), paint);
2641  canvas.Restore();
2642  }
2643 
2644  // Scale
2645  {
2646  canvas.Translate(Vector2(100, 0));
2647  canvas.Scale(Vector2(100, 100));
2648  Paint paint;
2649  paint.color_source = ColorSource::MakeImage(
2650  texture, Entity::TileMode::kRepeat, Entity::TileMode::kRepeat, {},
2651  Matrix::MakeScale(Vector2(0.005, 0.005)));
2652  canvas.DrawRect(Rect::MakeLTRB(0, 0, 1, 1), paint);
2653  }
2654 
2655  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2656 }

References impeller::Canvas::DrawPaint(), impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::Entity::kRepeat, impeller::ColorSource::MakeImage(), impeller::TRect< Scalar >::MakeLTRB(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeTranslation(), paint, impeller::Canvas::Restore(), impeller::Canvas::Rotate(), impeller::Canvas::Save(), impeller::Canvas::Scale(), impeller::Canvas::Translate(), and impeller::Color::White().

◆ TEST_P() [200/456]

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

Definition at line 1910 of file aiks_unittests.cc.

1910  {
1911  Canvas canvas;
1912  canvas.Scale(GetContentScale());
1913 
1914  auto test = [&canvas](const std::shared_ptr<ImageFilter>& filter) {
1915  auto DrawLine = [&canvas](const Point& p0, const Point& p1,
1916  const Paint& p) {
1917  auto path = PathBuilder{}
1918  .AddLine(p0, p1)
1919  .SetConvexity(Convexity::kConvex)
1920  .TakePath();
1921  Paint paint = p;
1922  paint.style = Paint::Style::kStroke;
1923  canvas.DrawPath(path, paint);
1924  };
1925  // Registration marks for the edge of the SaveLayer
1926  DrawLine(Point(75, 100), Point(225, 100), {.color = Color::White()});
1927  DrawLine(Point(75, 200), Point(225, 200), {.color = Color::White()});
1928  DrawLine(Point(100, 75), Point(100, 225), {.color = Color::White()});
1929  DrawLine(Point(200, 75), Point(200, 225), {.color = Color::White()});
1930 
1931  canvas.SaveLayer({.image_filter = filter},
1932  Rect::MakeLTRB(100, 100, 200, 200));
1933  {
1934  // DrawPaint to verify correct behavior when the contents are unbounded.
1935  canvas.DrawPaint({.color = Color::Yellow()});
1936 
1937  // Contrasting rectangle to see interior blurring
1938  canvas.DrawRect(Rect::MakeLTRB(125, 125, 175, 175),
1939  {.color = Color::Blue()});
1940  }
1941  canvas.Restore();
1942  };
1943 
1944  test(ImageFilter::MakeBlur(Sigma{10.0}, Sigma{10.0},
1945  FilterContents::BlurStyle::kNormal,
1946  Entity::TileMode::kDecal));
1947 
1948  canvas.Translate({200.0, 0.0});
1949 
1950  test(ImageFilter::MakeDilate(Radius{10.0}, Radius{10.0}));
1951 
1952  canvas.Translate({200.0, 0.0});
1953 
1954  test(ImageFilter::MakeErode(Radius{10.0}, Radius{10.0}));
1955 
1956  canvas.Translate({-400.0, 200.0});
1957 
1958  auto rotate_filter =
1959  ImageFilter::MakeMatrix(Matrix::MakeTranslation({150, 150}) *
1960  Matrix::MakeRotationZ(Degrees{10.0}) *
1961  Matrix::MakeTranslation({-150, -150}),
1962  SamplerDescriptor{});
1963  test(rotate_filter);
1964 
1965  canvas.Translate({200.0, 0.0});
1966 
1967  auto rgb_swap_filter = ImageFilter::MakeFromColorFilter(
1968  *ColorFilter::MakeMatrix({.array = {
1969  0, 1, 0, 0, 0, //
1970  0, 0, 1, 0, 0, //
1971  1, 0, 0, 0, 0, //
1972  0, 0, 0, 1, 0 //
1973  }}));
1974  test(rgb_swap_filter);
1975 
1976  canvas.Translate({200.0, 0.0});
1977 
1978  test(ImageFilter::MakeCompose(*rotate_filter, *rgb_swap_filter));
1979 
1980  canvas.Translate({-400.0, 200.0});
1981 
1982  test(ImageFilter::MakeLocalMatrix(Matrix::MakeTranslation({25.0, 25.0}),
1983  *rotate_filter));
1984 
1985  canvas.Translate({200.0, 0.0});
1986 
1987  test(ImageFilter::MakeLocalMatrix(Matrix::MakeTranslation({25.0, 25.0}),
1988  *rgb_swap_filter));
1989 
1990  canvas.Translate({200.0, 0.0});
1991 
1992  test(ImageFilter::MakeLocalMatrix(
1993  Matrix::MakeTranslation({25.0, 25.0}),
1994  *ImageFilter::MakeCompose(*rotate_filter, *rgb_swap_filter)));
1995 
1996  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1997 }

References impeller::PathBuilder::AddLine(), impeller::Color::Blue(), impeller::Canvas::DrawPaint(), impeller::Canvas::DrawPath(), impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::kConvex, impeller::Entity::kDecal, impeller::FilterContents::kNormal, impeller::Paint::kStroke, impeller::ImageFilter::MakeBlur(), impeller::ImageFilter::MakeCompose(), impeller::ImageFilter::MakeDilate(), impeller::ImageFilter::MakeErode(), impeller::ImageFilter::MakeFromColorFilter(), impeller::ImageFilter::MakeLocalMatrix(), impeller::TRect< Scalar >::MakeLTRB(), impeller::ColorFilter::MakeMatrix(), impeller::ImageFilter::MakeMatrix(), impeller::Matrix::MakeRotationZ(), impeller::Matrix::MakeTranslation(), paint, impeller::Canvas::Restore(), impeller::Canvas::SaveLayer(), impeller::Canvas::Scale(), impeller::PathBuilder::SetConvexity(), impeller::PathBuilder::TakePath(), impeller::Canvas::Translate(), impeller::Color::White(), and impeller::Color::Yellow().

◆ TEST_P() [201/456]

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

Definition at line 1999 of file aiks_unittests.cc.

1999  {
2000  Canvas canvas;
2001  canvas.Scale(GetContentScale());
2002 
2003  auto blur_filter = ImageFilter::MakeBlur(Sigma{10.0}, Sigma{10.0},
2004  FilterContents::BlurStyle::kNormal,
2005  Entity::TileMode::kDecal);
2006 
2007  canvas.SaveLayer({.image_filter = blur_filter}, std::nullopt);
2008  {
2009  // DrawPaint to verify correct behavior when the contents are unbounded.
2010  canvas.DrawPaint({.color = Color::Yellow()});
2011 
2012  // Contrasting rectangle to see interior blurring
2013  canvas.DrawRect(Rect::MakeLTRB(125, 125, 175, 175),
2014  {.color = Color::Blue()});
2015  }
2016  canvas.Restore();
2017 
2018  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2019 }

References impeller::Color::Blue(), impeller::Canvas::DrawPaint(), impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::Entity::kDecal, impeller::FilterContents::kNormal, impeller::ImageFilter::MakeBlur(), impeller::TRect< Scalar >::MakeLTRB(), impeller::Canvas::Restore(), impeller::Canvas::SaveLayer(), impeller::Canvas::Scale(), and impeller::Color::Yellow().

◆ TEST_P() [202/456]

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

Definition at line 1820 of file aiks_unittests.cc.

1820  {
1821  Canvas canvas;
1822 
1823  canvas.SaveLayer({
1824  .color_filter = ColorFilter::MakeLinearToSrgb(),
1825  });
1826 
1827  canvas.Translate({500, 300, 0});
1828  canvas.Rotate(Radians(2 * kPi / 3));
1829  canvas.DrawRect(Rect::MakeXYWH(100, 100, 200, 200), {.color = Color::Blue()});
1830 
1831  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1832 }

References impeller::Color::Blue(), impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::kPi, impeller::ColorFilter::MakeLinearToSrgb(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Canvas::Rotate(), impeller::Canvas::SaveLayer(), and impeller::Canvas::Translate().

◆ TEST_P() [203/456]

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

Definition at line 1198 of file aiks_blur_unittests.cc.

1198  {
1199  Scalar sigma = 70;
1200  auto callback = [&](AiksContext& renderer) -> std::optional<Picture> {
1201  if (AiksTest::ImGuiBegin("Controls", nullptr,
1202  ImGuiWindowFlags_AlwaysAutoResize)) {
1203  ImGui::SliderFloat("Sigma", &sigma, 0, 500);
1204  ImGui::End();
1205  }
1206  Canvas canvas;
1207  canvas.Scale(GetContentScale());
1208  canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)});
1209 
1210  std::shared_ptr<Texture> boston = CreateTextureForFixture("boston.jpg");
1211  ColorSource image_source = ColorSource::MakeImage(
1212  boston, Entity::TileMode::kRepeat, Entity::TileMode::kRepeat, {}, {});
1213 
1214  canvas.Transform(Matrix::MakeTranslation({100, 100, 0}) *
1215  Matrix::MakeScale({0.5, 0.5, 1.0}));
1216  Paint paint = {
1217  .color_source = image_source,
1218  .mask_blur_descriptor =
1219  Paint::MaskBlurDescriptor{
1220  .style = FilterContents::BlurStyle::kNormal,
1221  .sigma = Sigma(sigma),
1222  },
1223  };
1224  canvas.DrawRect(
1225  Rect::MakeXYWH(0, 0, boston->GetSize().width, boston->GetSize().height),
1226  paint);
1227 
1228  return canvas.EndRecordingAsPicture();
1229  };
1230  ASSERT_TRUE(OpenPlaygroundHere(callback));
1231 }

References impeller::Canvas::DrawPaint(), impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::AiksPlayground::ImGuiBegin(), impeller::FilterContents::kNormal, impeller::Entity::kRepeat, impeller::ColorSource::MakeImage(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeTranslation(), impeller::TRect< Scalar >::MakeXYWH(), paint, impeller::Canvas::Scale(), impeller::Paint::MaskBlurDescriptor::style, and impeller::Canvas::Transform().

◆ TEST_P() [204/456]

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

Definition at line 990 of file aiks_blur_unittests.cc.

990  {
991  Scalar sigma = 30;
992  auto callback = [&](AiksContext& renderer) -> std::optional<Picture> {
993  if (AiksTest::ImGuiBegin("Controls", nullptr,
994  ImGuiWindowFlags_AlwaysAutoResize)) {
995  ImGui::SliderFloat("Sigma", &sigma, 0, 500);
996  ImGui::End();
997  }
998  Canvas canvas;
999  canvas.Scale(GetContentScale());
1000  Paint paint;
1001  paint.color = Color::Green();
1002  paint.mask_blur_descriptor = Paint::MaskBlurDescriptor{
1003  .style = FilterContents::BlurStyle::kNormal,
1004  .sigma = Sigma(sigma),
1005  };
1006  std::shared_ptr<Texture> boston = CreateTextureForFixture("boston.jpg");
1007  canvas.DrawImage(std::make_shared<Image>(boston), {200, 200}, paint);
1008  Paint red;
1009  red.color = Color::Red();
1010  canvas.DrawRect(Rect::MakeXYWH(0, 0, 200, 200), red);
1011  return canvas.EndRecordingAsPicture();
1012  };
1013  ASSERT_TRUE(OpenPlaygroundHere(callback));
1014 }

References impeller::Paint::color, impeller::Canvas::DrawImage(), impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::Green(), impeller::AiksPlayground::ImGuiBegin(), impeller::FilterContents::kNormal, impeller::TRect< Scalar >::MakeXYWH(), paint, impeller::Color::Red(), impeller::Canvas::Scale(), and impeller::Paint::MaskBlurDescriptor::style.

◆ TEST_P() [205/456]

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

Definition at line 277 of file aiks_blur_unittests.cc.

277  {
278  Canvas canvas;
279 
280  Paint paint = {
281  .color = Color::Blue(),
282  .mask_blur_descriptor =
283  Paint::MaskBlurDescriptor{
284  .style = FilterContents::BlurStyle::kNormal,
285  .sigma = Sigma(0),
286  },
287  };
288 
289  canvas.DrawCircle({300, 300}, 200, paint);
290  canvas.DrawRect(Rect::MakeLTRB(100, 300, 500, 600), paint);
291 
292  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
293 }

References impeller::Color::Blue(), impeller::Canvas::DrawCircle(), impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::FilterContents::kNormal, impeller::TRect< Scalar >::MakeLTRB(), paint, and impeller::Paint::MaskBlurDescriptor::style.

◆ TEST_P() [206/456]

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

Definition at line 2366 of file aiks_unittests.cc.

2366  {
2367  Canvas canvas;
2368  canvas.DrawPaint({.color = Color::Black()});
2369  canvas.SaveLayer({}, std::nullopt);
2370  {
2371  canvas.DrawCircle(Point(200, 200), 100,
2372  {.color = Color::Green().WithAlpha(0.5),
2373  .blend_mode = BlendMode::kPlus});
2374  // Should render a second circle, centered on the bottom-right-most edge of
2375  // the circle.
2376  canvas.SaveLayer(
2377  {}, std::nullopt,
2378  ImageFilter::MakeMatrix(
2379  Matrix::MakeTranslation(Vector2(1, 1) * (100 + 100 * k1OverSqrt2)) *
2380  Matrix::MakeScale(Vector2(1, 1) * 0.5) *
2381  Matrix::MakeTranslation(Vector2(-100, -100)),
2382  SamplerDescriptor{}));
2383  canvas.Restore();
2384  }
2385  canvas.Restore();
2386 
2387  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2388 }

References impeller::Color::Black(), impeller::Canvas::DrawCircle(), impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::Green(), impeller::k1OverSqrt2, impeller::kPlus, impeller::ImageFilter::MakeMatrix(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeTranslation(), impeller::Canvas::Restore(), impeller::Canvas::SaveLayer(), and impeller::Color::WithAlpha().

◆ TEST_P() [207/456]

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

Definition at line 2530 of file aiks_unittests.cc.

2531  {
2532  Canvas canvas;
2533  canvas.Scale(GetContentScale());
2534  canvas.Translate({100, 100});
2535  // Draw a circle in a SaveLayer at -300, but move it back on-screen with a
2536  // +300 translation applied by a SaveLayer image filter.
2537  canvas.SaveLayer({
2538  .image_filter = std::make_shared<MatrixImageFilter>(
2539  Matrix::MakeTranslation({300, 0}) * Matrix::MakeScale({2, 2, 2}),
2540  SamplerDescriptor{}),
2541  });
2542  canvas.DrawCircle({-150, 0}, 50, {.color = Color::Green()});
2543  canvas.Restore();
2544 
2545  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2546 }

References impeller::Canvas::DrawCircle(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::Green(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeTranslation(), impeller::Canvas::Restore(), impeller::Canvas::SaveLayer(), impeller::Canvas::Scale(), and impeller::Canvas::Translate().

◆ TEST_P() [208/456]

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

Definition at line 2513 of file aiks_unittests.cc.

2513  {
2514  Canvas canvas;
2515  canvas.Scale(GetContentScale());
2516  canvas.Translate({100, 100});
2517  // Draw a circle in a SaveLayer at -300, but move it back on-screen with a
2518  // +300 translation applied by a SaveLayer image filter.
2519  canvas.SaveLayer({
2520  .image_filter = std::make_shared<MatrixImageFilter>(
2521  Matrix::MakeTranslation({300, 0}), SamplerDescriptor{}),
2522  });
2523  canvas.DrawCircle({-300, 0}, 100, {.color = Color::Green()});
2524  canvas.Restore();
2525 
2526  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2527 }

References impeller::Canvas::DrawCircle(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::Green(), impeller::Matrix::MakeTranslation(), impeller::Canvas::Restore(), impeller::Canvas::SaveLayer(), impeller::Canvas::Scale(), and impeller::Canvas::Translate().

◆ TEST_P() [209/456]

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

Definition at line 2486 of file aiks_unittests.cc.

2486  {
2487  Scalar scale = 2.0;
2488  auto callback = [&](AiksContext& renderer) -> std::optional<Picture> {
2489  if (AiksTest::ImGuiBegin("Controls", nullptr,
2490  ImGuiWindowFlags_AlwaysAutoResize)) {
2491  ImGui::SliderFloat("Scale", &scale, 1, 2);
2492  ImGui::End();
2493  }
2494  Canvas canvas;
2495  canvas.Scale(GetContentScale());
2496  auto image =
2497  std::make_shared<Image>(CreateTextureForFixture("airplane.jpg"));
2498  canvas.Translate({600, -200});
2499  canvas.SaveLayer({
2500  .image_filter = std::make_shared<MatrixImageFilter>(
2501  Matrix::MakeScale({scale, scale, 1}), SamplerDescriptor{}),
2502  });
2503  canvas.DrawImage(image, {0, 0},
2504  Paint{.color = Color::White().WithAlpha(0.5)});
2505  canvas.Restore();
2506  return canvas.EndRecordingAsPicture();
2507  };
2508 
2509  ASSERT_TRUE(OpenPlaygroundHere(callback));
2510 }

References impeller::Paint::color, impeller::Canvas::DrawImage(), impeller::Canvas::EndRecordingAsPicture(), impeller::AiksPlayground::ImGuiBegin(), impeller::Matrix::MakeScale(), impeller::Canvas::Restore(), impeller::Canvas::SaveLayer(), impeller::Canvas::Scale(), scale, impeller::Canvas::Translate(), impeller::Color::White(), and impeller::Color::WithAlpha().

◆ TEST_P() [210/456]

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

Definition at line 2339 of file aiks_unittests.cc.

2339  {
2340  Canvas canvas;
2341  canvas.DrawPaint({.color = Color::Black()});
2342  canvas.SaveLayer({}, std::nullopt);
2343  {
2344  canvas.DrawCircle(Point(200, 200), 100,
2345  {.color = Color::Green().WithAlpha(0.5),
2346  .blend_mode = BlendMode::kPlus});
2347  // Should render a second circle, centered on the bottom-right-most edge of
2348  // the circle.
2349  canvas.SaveLayer({.image_filter = ImageFilter::MakeMatrix(
2350  Matrix::MakeTranslation(Vector2(1, 1) *
2351  (200 + 100 * k1OverSqrt2)) *
2352  Matrix::MakeScale(Vector2(1, 1) * 0.5) *
2353  Matrix::MakeTranslation(Vector2(-200, -200)),
2354  SamplerDescriptor{})},
2355  std::nullopt);
2356  canvas.DrawCircle(Point(200, 200), 100,
2357  {.color = Color::Green().WithAlpha(0.5),
2358  .blend_mode = BlendMode::kPlus});
2359  canvas.Restore();
2360  }
2361  canvas.Restore();
2362 
2363  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2364 }

References impeller::Color::Black(), impeller::Canvas::DrawCircle(), impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::Green(), impeller::k1OverSqrt2, impeller::kPlus, impeller::ImageFilter::MakeMatrix(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeTranslation(), impeller::Canvas::Restore(), impeller::Canvas::SaveLayer(), and impeller::Color::WithAlpha().

◆ TEST_P() [211/456]

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

Definition at line 2785 of file aiks_unittests.cc.

2785  {
2786  TextureDescriptor texture_descriptor;
2787  texture_descriptor.size = ISize{1024, 1024};
2788  texture_descriptor.format = PixelFormat::kR8G8B8A8UNormInt;
2789  texture_descriptor.storage_mode = StorageMode::kHostVisible;
2790  texture_descriptor.mip_count = texture_descriptor.size.MipCount();
2791 
2792  std::vector<uint8_t> bytes(4194304);
2793  bool alternate = false;
2794  for (auto i = 0u; i < 4194304; i += 4) {
2795  if (alternate) {
2796  bytes[i] = 255;
2797  bytes[i + 1] = 0;
2798  bytes[i + 2] = 0;
2799  bytes[i + 3] = 255;
2800  } else {
2801  bytes[i] = 0;
2802  bytes[i + 1] = 255;
2803  bytes[i + 2] = 0;
2804  bytes[i + 3] = 255;
2805  }
2806  alternate = !alternate;
2807  }
2808 
2809  ASSERT_EQ(texture_descriptor.GetByteSizeOfBaseMipLevel(), bytes.size());
2810  auto mapping = std::make_shared<fml::NonOwnedMapping>(
2811  bytes.data(), // data
2812  texture_descriptor.GetByteSizeOfBaseMipLevel() // size
2813  );
2814  auto texture =
2815  GetContext()->GetResourceAllocator()->CreateTexture(texture_descriptor);
2816 
2817  auto device_buffer =
2818  GetContext()->GetResourceAllocator()->CreateBufferWithCopy(*mapping);
2819  auto command_buffer = GetContext()->CreateCommandBuffer();
2820  auto blit_pass = command_buffer->CreateBlitPass();
2821 
2822  blit_pass->AddCopy(DeviceBuffer::AsBufferView(std::move(device_buffer)),
2823  texture);
2824  blit_pass->GenerateMipmap(texture);
2825  EXPECT_TRUE(blit_pass->EncodeCommands(GetContext()->GetResourceAllocator()));
2826  EXPECT_TRUE(GetContext()->GetCommandQueue()->Submit({command_buffer}).ok());
2827 
2828  auto image = std::make_shared<Image>(texture);
2829 
2830  Canvas canvas;
2831  canvas.DrawImageRect(image, Rect::MakeSize(texture->GetSize()),
2832  Rect::MakeLTRB(0, 0, 100, 100), {});
2833 
2834  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2835 }

References impeller::DeviceBuffer::AsBufferView(), impeller::Canvas::DrawImageRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::TextureDescriptor::format, impeller::TextureDescriptor::GetByteSizeOfBaseMipLevel(), impeller::kHostVisible, impeller::kR8G8B8A8UNormInt, impeller::TRect< Scalar >::MakeLTRB(), impeller::TRect< Scalar >::MakeSize(), impeller::TextureDescriptor::mip_count, impeller::TSize< T >::MipCount(), impeller::TextureDescriptor::size, and impeller::TextureDescriptor::storage_mode.

◆ TEST_P() [212/456]

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

Definition at line 2137 of file aiks_unittests.cc.

2137  {
2138  Canvas canvas;
2139  canvas.Scale(Vector2(1.618, 1.618));
2140  canvas.DrawCircle(Point(), 10,
2141  {
2142  .color = Color::CornflowerBlue(),
2143  .blend_mode = BlendMode::kSourceOver,
2144  });
2145  Picture picture = canvas.EndRecordingAsPicture();
2146 
2147  // Extract the SolidColorSource.
2148  // Entity entity;
2149  std::vector<Entity> entity;
2150  std::shared_ptr<SolidColorContents> contents;
2151  picture.pass->IterateAllEntities([e = &entity, &contents](Entity& entity) {
2152  if (ScalarNearlyEqual(entity.GetTransform().GetScale().x, 1.618f)) {
2153  contents =
2154  std::static_pointer_cast<SolidColorContents>(entity.GetContents());
2155  e->emplace_back(entity.Clone());
2156  return false;
2157  }
2158  return true;
2159  });
2160 
2161  ASSERT_TRUE(entity.size() >= 1);
2162  ASSERT_TRUE(contents->IsOpaque());
2163  ASSERT_EQ(entity[0].GetBlendMode(), BlendMode::kSource);
2164 }

References impeller::Entity::Clone(), impeller::Color::CornflowerBlue(), impeller::Canvas::DrawCircle(), impeller::Canvas::EndRecordingAsPicture(), impeller::Entity::GetContents(), impeller::Matrix::GetScale(), impeller::Entity::GetTransform(), impeller::kSource, impeller::kSourceOver, impeller::Picture::pass, impeller::ScalarNearlyEqual(), impeller::Canvas::Scale(), and impeller::Vector3::x.

◆ TEST_P() [213/456]

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

Definition at line 114 of file aiks_blend_unittests.cc.

114  {
115  Paint paint;
116  Canvas canvas;
117  // Default is kSourceOver.
118  paint.color = Color(1, 0, 0, 0.5);
119  canvas.DrawCircle(Point(150, 200), 100, paint);
120  paint.color = Color(0, 1, 0, 0.5);
121  canvas.DrawCircle(Point(250, 200), 100, paint);
122 
123  paint.blend_mode = BlendMode::kPlus;
124  paint.color = Color::Red();
125  canvas.DrawCircle(Point(450, 250), 100, paint);
126  paint.color = Color::Green();
127  canvas.DrawCircle(Point(550, 250), 100, paint);
128  paint.color = Color::Blue();
129  canvas.DrawCircle(Point(500, 150), 100, paint);
130  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
131 }

References impeller::Color::Blue(), impeller::Canvas::DrawCircle(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::Green(), impeller::kPlus, paint, and impeller::Color::Red().

◆ TEST_P() [214/456]

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

Definition at line 1567 of file aiks_unittests.cc.

1567  {
1568  // validate that a paint with a color filter "HasFilters", no other filters
1569  // impact this setting.
1570  Paint paint;
1571 
1572  ASSERT_FALSE(paint.HasColorFilter());
1573 
1574  paint.color_filter =
1575  ColorFilter::MakeBlend(BlendMode::kSourceOver, Color::Blue());
1576 
1577  ASSERT_TRUE(paint.HasColorFilter());
1578 
1579  paint.image_filter = ImageFilter::MakeBlur(Sigma(1.0), Sigma(1.0),
1580  FilterContents::BlurStyle::kNormal,
1581  Entity::TileMode::kClamp);
1582 
1583  ASSERT_TRUE(paint.HasColorFilter());
1584 
1585  paint.mask_blur_descriptor = {};
1586 
1587  ASSERT_TRUE(paint.HasColorFilter());
1588 
1589  paint.color_filter = nullptr;
1590 
1591  ASSERT_FALSE(paint.HasColorFilter());
1592 }

References impeller::Color::Blue(), impeller::Entity::kClamp, impeller::FilterContents::kNormal, impeller::kSourceOver, impeller::ColorFilter::MakeBlend(), impeller::ImageFilter::MakeBlur(), and paint.

◆ TEST_P() [215/456]

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

Definition at line 1618 of file aiks_unittests.cc.

1619  {
1620  Canvas canvas;
1621  canvas.SaveLayer({}, std::nullopt, ImageFilter::MakeMatrix(Matrix(), {}));
1622  canvas.DrawPaint({.color = Color::Red(), .blend_mode = BlendMode::kSource});
1623  canvas.DrawPaint({.color = Color::CornflowerBlue().WithAlpha(0.75),
1624  .blend_mode = BlendMode::kSourceOver});
1625  canvas.Restore();
1626 
1627  Picture picture = canvas.EndRecordingAsPicture();
1628 
1629  std::shared_ptr<ContextSpy> spy = ContextSpy::Make();
1630  std::shared_ptr<Context> real_context = GetContext();
1631  std::shared_ptr<ContextMock> mock_context = spy->MakeContext(real_context);
1632  AiksContext renderer(mock_context, nullptr);
1633  std::shared_ptr<Image> image = picture.ToImage(renderer, {300, 300});
1634 
1635  ASSERT_EQ(spy->render_passes_.size(),
1636  GetBackend() == PlaygroundBackend::kOpenGLES ? 4llu : 3llu);
1637  std::shared_ptr<RenderPass> render_pass = spy->render_passes_[0];
1638  ASSERT_EQ(render_pass->GetCommands().size(), 0llu);
1639 }

References impeller::Color::CornflowerBlue(), impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), impeller::kOpenGLES, impeller::kSource, impeller::kSourceOver, impeller::ImageFilter::MakeMatrix(), impeller::Color::Red(), impeller::Canvas::Restore(), impeller::Canvas::SaveLayer(), impeller::Picture::ToImage(), and impeller::Color::WithAlpha().

◆ TEST_P() [216/456]

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

Definition at line 2430 of file aiks_unittests.cc.

2430  {
2431  Canvas canvas;
2432 
2433  // Should render a green square in the middle of a blue circle.
2434  canvas.SaveLayer({});
2435  {
2436  canvas.Translate(Point(100, 100));
2437  canvas.DrawCircle(Point(200, 200), 200, {.color = Color::Blue()});
2438  canvas.ClipRect(Rect::MakeXYWH(100, 100, 200, 200));
2439  canvas.DrawCircle(Point(200, 200), 200,
2440  {
2441  .color = Color::Green(),
2442  .blend_mode = BlendMode::kSourceOver,
2443  .image_filter = ImageFilter::MakeFromColorFilter(
2444  *ColorFilter::MakeBlend(BlendMode::kDestination,
2445  Color::White())),
2446  });
2447  canvas.Restore();
2448  }
2449 
2450  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2451 }

References impeller::Color::Blue(), impeller::Canvas::ClipRect(), impeller::Canvas::DrawCircle(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::Green(), impeller::kDestination, impeller::kSourceOver, impeller::ColorFilter::MakeBlend(), impeller::ImageFilter::MakeFromColorFilter(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Canvas::Restore(), impeller::Canvas::SaveLayer(), impeller::Canvas::Translate(), and impeller::Color::White().

◆ TEST_P() [217/456]

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

Definition at line 2454 of file aiks_unittests.cc.

2454  {
2455  auto context = MakeContext();
2456  std::weak_ptr<Texture> weak_texture;
2457 
2458  {
2459  auto texture = CreateTextureForFixture("table_mountain_nx.png");
2460 
2461  Canvas canvas;
2462  canvas.Scale(GetContentScale());
2463  canvas.Translate({100.0f, 100.0f, 0});
2464 
2465  Paint paint;
2466  paint.color_source = ColorSource::MakeImage(
2467  texture, Entity::TileMode::kClamp, Entity::TileMode::kClamp, {}, {});
2468  canvas.DrawRect(Rect::MakeXYWH(0, 0, 600, 600), paint);
2469 
2470  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2471  }
2472 
2473  // See https://github.com/flutter/flutter/issues/134751.
2474  //
2475  // If the fence waiter was working this may not be released by the end of the
2476  // scope above. Adding a manual shutdown so that future changes to the fence
2477  // waiter will not flake this test.
2478  context->Shutdown();
2479 
2480  // The texture should be released by now.
2481  ASSERT_TRUE(weak_texture.expired()) << "When the texture is no longer in use "
2482  "by the backend, it should be "
2483  "released.";
2484 }

References impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::Entity::kClamp, impeller::ColorSource::MakeImage(), impeller::TRect< Scalar >::MakeXYWH(), paint, impeller::Canvas::Scale(), and impeller::Canvas::Translate().

◆ TEST_P() [218/456]

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

Definition at line 19 of file aiks_dl_path_unittests.cc.

19  {
20  DisplayListBuilder builder;
21  builder.Transform(SkMatrix::Translate(300, 300) * SkMatrix::RotateDeg(90));
22 
23  SkPath arrow_stem;
24  SkPath arrow_head;
25 
26  arrow_stem.moveTo({120, 190}).lineTo({120, 50});
27  arrow_head.moveTo({50, 120}).lineTo({120, 190}).lineTo({190, 120});
28 
29  auto filter =
30  DlBlendColorFilter::Make(DlColor::kAliceBlue(), DlBlendMode::kSrcIn);
31 
32  DlPaint paint;
33  paint.setStrokeWidth(15.0);
34  paint.setStrokeCap(DlStrokeCap::kRound);
35  paint.setStrokeJoin(DlStrokeJoin::kRound);
36  paint.setDrawStyle(DlDrawStyle::kStroke);
37  paint.setColorFilter(filter);
38  paint.setColor(DlColor::kBlack());
39 
40  builder.DrawPath(arrow_stem, paint);
41  builder.DrawPath(arrow_head, paint);
42 
43  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
44 }

References paint.

◆ TEST_P() [219/456]

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

Definition at line 1415 of file aiks_unittests.cc.

1415  {
1416  // Compare with https://fiddle.skia.org/c/9e03de8567ffb49e7e83f53b64bcf636
1417  Canvas canvas;
1418  Paint paint;
1419 
1420  paint.color = Color::Black();
1421  Rect rect = Rect::MakeXYWH(25, 25, 25, 25);
1422  canvas.DrawRect(rect, paint);
1423 
1424  canvas.Translate({10, 10});
1425  canvas.SaveLayer({});
1426 
1427  paint.color = Color::Green();
1428  canvas.DrawRect(rect, paint);
1429 
1430  canvas.Restore();
1431 
1432  canvas.Translate({10, 10});
1433  paint.color = Color::Red();
1434  canvas.DrawRect(rect, paint);
1435 
1436  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1437 }

References impeller::Color::Black(), impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::Green(), impeller::TRect< Scalar >::MakeXYWH(), paint, impeller::Color::Red(), impeller::Canvas::Restore(), impeller::Canvas::SaveLayer(), and impeller::Canvas::Translate().

◆ TEST_P() [220/456]

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

Definition at line 1496 of file aiks_unittests.cc.

1496  {
1497  Canvas canvas;
1498  canvas.Scale(GetContentScale());
1499  canvas.Translate(Vector2(100, 100));
1500 
1501  auto texture = std::make_shared<Image>(CreateTextureForFixture("boston.jpg"));
1502  auto draw_image_layer = [&canvas, &texture](const Paint& paint) {
1503  canvas.SaveLayer(paint);
1504  canvas.DrawImage(texture, {}, Paint{});
1505  canvas.Restore();
1506  };
1507 
1508  Paint effect_paint;
1509  effect_paint.mask_blur_descriptor = Paint::MaskBlurDescriptor{
1510  .style = FilterContents::BlurStyle::kNormal,
1511  .sigma = Sigma{6},
1512  };
1513  draw_image_layer(effect_paint);
1514 
1515  canvas.Translate(Vector2(300, 300));
1516  canvas.Scale(Vector2(3, 3));
1517  draw_image_layer(effect_paint);
1518 
1519  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1520 }

References impeller::Canvas::DrawImage(), impeller::Canvas::EndRecordingAsPicture(), impeller::FilterContents::kNormal, impeller::Paint::mask_blur_descriptor, paint, impeller::Canvas::Restore(), impeller::Canvas::SaveLayer(), impeller::Canvas::Scale(), impeller::Paint::MaskBlurDescriptor::style, and impeller::Canvas::Translate().

◆ TEST_P() [221/456]

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

Definition at line 2878 of file aiks_unittests.cc.

2878  {
2879  auto bridge = CreateTextureForFixture("bay_bridge.jpg");
2880 
2881  // Replace part of the texture with a red rectangle.
2882  std::vector<uint8_t> bytes(100 * 100 * 4);
2883  for (auto i = 0u; i < bytes.size(); i += 4) {
2884  bytes[i] = 255;
2885  bytes[i + 1] = 0;
2886  bytes[i + 2] = 0;
2887  bytes[i + 3] = 255;
2888  }
2889  auto mapping =
2890  std::make_shared<fml::NonOwnedMapping>(bytes.data(), bytes.size());
2891  auto device_buffer =
2892  GetContext()->GetResourceAllocator()->CreateBufferWithCopy(*mapping);
2893  auto cmd_buffer = GetContext()->CreateCommandBuffer();
2894  auto blit_pass = cmd_buffer->CreateBlitPass();
2895  blit_pass->AddCopy(DeviceBuffer::AsBufferView(device_buffer), bridge,
2896  IRect::MakeLTRB(50, 50, 150, 150));
2897 
2898  auto did_submit =
2899  blit_pass->EncodeCommands(GetContext()->GetResourceAllocator()) &&
2900  GetContext()->GetCommandQueue()->Submit({std::move(cmd_buffer)}).ok();
2901  ASSERT_TRUE(did_submit);
2902 
2903  auto image = std::make_shared<Image>(bridge);
2904 
2905  Canvas canvas;
2906  canvas.DrawImage(image, {0, 0}, {});
2907 
2908  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2909 }

References impeller::DeviceBuffer::AsBufferView(), impeller::Canvas::DrawImage(), impeller::Canvas::EndRecordingAsPicture(), and impeller::TRect< T >::MakeLTRB().

◆ TEST_P() [222/456]

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

Definition at line 1439 of file aiks_unittests.cc.

1439  {
1440  Canvas canvas;
1441  Paint paint;
1442  Rect rect = Rect::MakeXYWH(0, 0, 1000, 1000);
1443 
1444  // Black, green, and red squares offset by [10, 10].
1445  {
1446  canvas.SaveLayer({}, Rect::MakeXYWH(25, 25, 25, 25));
1447  paint.color = Color::Black();
1448  canvas.DrawRect(rect, paint);
1449  canvas.Restore();
1450  }
1451 
1452  {
1453  canvas.SaveLayer({}, Rect::MakeXYWH(35, 35, 25, 25));
1454  paint.color = Color::Green();
1455  canvas.DrawRect(rect, paint);
1456  canvas.Restore();
1457  }
1458 
1459  {
1460  canvas.SaveLayer({}, Rect::MakeXYWH(45, 45, 25, 25));
1461  paint.color = Color::Red();
1462  canvas.DrawRect(rect, paint);
1463  canvas.Restore();
1464  }
1465 
1466  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1467 }

References impeller::Color::Black(), impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::Green(), impeller::TRect< Scalar >::MakeXYWH(), paint, impeller::Color::Red(), impeller::Canvas::Restore(), and impeller::Canvas::SaveLayer().

◆ TEST_P() [223/456]

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

Definition at line 2390 of file aiks_unittests.cc.

2390  {
2391  auto contents = SolidColorContents();
2392  contents.SetColor(Color::CornflowerBlue().WithAlpha(0.75));
2393  auto result = contents.ApplyColorFilter([](const Color& color) {
2394  return color.Blend(Color::LimeGreen().WithAlpha(0.75), BlendMode::kScreen);
2395  });
2396  ASSERT_TRUE(result);
2397  ASSERT_COLOR_NEAR(contents.GetColor(),
2398  Color(0.424452, 0.828743, 0.79105, 0.9375));
2399 }

References ASSERT_COLOR_NEAR, color, impeller::Color::CornflowerBlue(), impeller::kScreen, and impeller::Color::LimeGreen().

◆ TEST_P() [224/456]

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

Definition at line 1200 of file aiks_unittests.cc.

1200  {
1201  Canvas canvas;
1202  canvas.Scale(GetContentScale());
1203  Paint paint;
1204  paint.mask_blur_descriptor = Paint::MaskBlurDescriptor{
1205  .style = FilterContents::BlurStyle::kNormal,
1206  .sigma = Sigma{1},
1207  };
1208 
1209  canvas.DrawPaint({.color = Color::White()});
1210 
1211  paint.color = Color::Crimson();
1212  Scalar y = 100.0f;
1213  for (int i = 0; i < 5; i++) {
1214  Scalar x = (i + 1) * 100;
1215  Scalar radius = x / 10.0f;
1216  canvas.DrawRect(Rect::MakeXYWH(x + 25 - radius / 2, y + radius / 2, //
1217  radius, 60.0f - radius),
1218  paint);
1219  }
1220 
1221  paint.color = Color::Blue();
1222  y += 100.0f;
1223  for (int i = 0; i < 5; i++) {
1224  Scalar x = (i + 1) * 100;
1225  Scalar radius = x / 10.0f;
1226  canvas.DrawCircle({x + 25, y + 25}, radius, paint);
1227  }
1228 
1229  paint.color = Color::Green();
1230  y += 100.0f;
1231  for (int i = 0; i < 5; i++) {
1232  Scalar x = (i + 1) * 100;
1233  Scalar radius = x / 10.0f;
1234  canvas.DrawOval(Rect::MakeXYWH(x + 25 - radius / 2, y + radius / 2, //
1235  radius, 60.0f - radius),
1236  paint);
1237  }
1238 
1239  paint.color = Color::Purple();
1240  y += 100.0f;
1241  for (int i = 0; i < 5; i++) {
1242  Scalar x = (i + 1) * 100;
1243  Scalar radius = x / 20.0f;
1244  canvas.DrawRRect(Rect::MakeXYWH(x, y, 60.0f, 60.0f), //
1245  {radius, radius}, //
1246  paint);
1247  }
1248 
1249  paint.color = Color::Orange();
1250  y += 100.0f;
1251  for (int i = 0; i < 5; i++) {
1252  Scalar x = (i + 1) * 100;
1253  Scalar radius = x / 20.0f;
1254  canvas.DrawRRect(Rect::MakeXYWH(x, y, 60.0f, 60.0f), //
1255  {radius, 5.0f}, paint);
1256  }
1257 
1258  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1259 }

References impeller::Color::Blue(), impeller::Color::Crimson(), impeller::Canvas::DrawCircle(), impeller::Canvas::DrawOval(), impeller::Canvas::DrawPaint(), impeller::Canvas::DrawRect(), impeller::Canvas::DrawRRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::Green(), impeller::FilterContents::kNormal, impeller::TRect< Scalar >::MakeXYWH(), impeller::Color::Orange(), paint, impeller::Color::Purple(), impeller::Canvas::Scale(), impeller::Paint::MaskBlurDescriptor::style, and impeller::Color::White().

◆ TEST_P() [225/456]

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

Definition at line 187 of file aiks_path_unittests.cc.

187  {
188  // Compare with https://fiddle.skia.org/c/027392122bec8ac2b5d5de00a4b9bbe2
189  auto callback = [&](AiksContext& renderer) -> std::optional<Picture> {
190  static Color color = Color::Black().WithAlpha(0.5);
191  static float scale = 3;
192  static bool add_circle_clip = true;
193 
194  if (AiksTest::ImGuiBegin("Controls", nullptr,
195  ImGuiWindowFlags_AlwaysAutoResize)) {
196  ImGui::ColorEdit4("Color", reinterpret_cast<float*>(&color));
197  ImGui::SliderFloat("Scale", &scale, 0, 6);
198  ImGui::Checkbox("Circle clip", &add_circle_clip);
199  ImGui::End();
200  }
201 
202  Canvas canvas;
203  canvas.Scale(GetContentScale());
204  Paint paint;
205 
206  paint.color = Color::White();
207  canvas.DrawPaint(paint);
208 
209  paint.color = color;
210  paint.style = Paint::Style::kStroke;
211  paint.stroke_width = 10;
212 
213  Path path = PathBuilder{}
214  .MoveTo({20, 20})
215  .QuadraticCurveTo({60, 20}, {60, 60})
216  .Close()
217  .MoveTo({60, 20})
218  .QuadraticCurveTo({60, 60}, {20, 60})
219  .TakePath();
220 
221  canvas.Scale(Vector2(scale, scale));
222 
223  if (add_circle_clip) {
224  static PlaygroundPoint circle_clip_point_a(Point(60, 300), 20,
225  Color::Red());
226  static PlaygroundPoint circle_clip_point_b(Point(600, 300), 20,
227  Color::Red());
228  auto [handle_a, handle_b] =
229  DrawPlaygroundLine(circle_clip_point_a, circle_clip_point_b);
230 
231  auto screen_to_canvas = canvas.GetCurrentTransform().Invert();
232  Point point_a = screen_to_canvas * handle_a * GetContentScale();
233  Point point_b = screen_to_canvas * handle_b * GetContentScale();
234 
235  Point middle = (point_a + point_b) / 2;
236  auto radius = point_a.GetDistance(middle);
237  canvas.ClipPath(PathBuilder{}.AddCircle(middle, radius).TakePath());
238  }
239 
240  for (auto join : {Join::kBevel, Join::kRound, Join::kMiter}) {
241  paint.stroke_join = join;
242  for (auto cap : {Cap::kButt, Cap::kSquare, Cap::kRound}) {
243  paint.stroke_cap = cap;
244  canvas.DrawPath(path, paint);
245  canvas.Translate({80, 0});
246  }
247  canvas.Translate({-240, 60});
248  }
249 
250  return canvas.EndRecordingAsPicture();
251  };
252 
253  ASSERT_TRUE(OpenPlaygroundHere(callback));
254 }

References impeller::PathBuilder::AddCircle(), impeller::Color::Black(), impeller::Canvas::ClipPath(), impeller::Close(), color, impeller::Canvas::DrawPaint(), impeller::Canvas::DrawPath(), impeller::DrawPlaygroundLine(), impeller::Canvas::EndRecordingAsPicture(), impeller::Canvas::GetCurrentTransform(), impeller::TPoint< T >::GetDistance(), impeller::AiksPlayground::ImGuiBegin(), impeller::Matrix::Invert(), impeller::kBevel, impeller::kButt, impeller::kMiter, impeller::kRound, impeller::kSquare, impeller::Paint::kStroke, impeller::PathBuilder::MoveTo(), paint, impeller::Color::Red(), impeller::Canvas::Scale(), scale, impeller::PathBuilder::TakePath(), impeller::Canvas::Translate(), impeller::Color::White(), and impeller::Color::WithAlpha().

◆ TEST_P() [226/456]

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

Definition at line 1834 of file aiks_unittests.cc.

1834  {
1835  Canvas canvas;
1836 
1837  canvas.SaveLayer({
1838  .color_filter = ColorFilter::MakeSrgbToLinear(),
1839  });
1840 
1841  canvas.Translate({500, 300, 0});
1842  canvas.Rotate(Radians(2 * kPi / 3));
1843  canvas.DrawRect(Rect::MakeXYWH(100, 100, 200, 200), {.color = Color::Blue()});
1844 
1845  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1846 }

References impeller::Color::Blue(), impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::kPi, impeller::ColorFilter::MakeSrgbToLinear(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Canvas::Rotate(), impeller::Canvas::SaveLayer(), and impeller::Canvas::Translate().

◆ TEST_P() [227/456]

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

Definition at line 982 of file aiks_unittests.cc.

982  {
983  Canvas canvas;
984  canvas.Scale(GetContentScale());
985  Paint paint;
986  const int color_count = 3;
987  Color colors[color_count] = {
988  Color::Blue(),
989  Color::Green(),
990  Color::Crimson(),
991  };
992 
993  paint.color = Color::White();
994  canvas.DrawPaint(paint);
995 
996  int c_index = 0;
997 
998  auto draw = [&paint, &colors, &c_index](Canvas& canvas, Point center,
999  Scalar r, Scalar dr, int n) {
1000  for (int i = 0; i < n; i++) {
1001  paint.color = colors[(c_index++) % color_count];
1002  canvas.DrawCircle(center, r, paint);
1003  r += dr;
1004  }
1005  };
1006 
1007  paint.style = Paint::Style::kStroke;
1008  paint.stroke_width = 1;
1009  draw(canvas, {10, 10}, 2, 2, 14); // r = [2, 28], covers [1,29]
1010  paint.stroke_width = 5;
1011  draw(canvas, {10, 10}, 35, 10, 56); // r = [35, 585], covers [30,590]
1012 
1013  std::vector<Color> gradient_colors = {
1014  Color{0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0},
1015  Color{0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0},
1016  Color{0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0},
1017  Color{0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0},
1018  Color{0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0},
1019  Color{0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0},
1020  Color{0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0}};
1021  std::vector<Scalar> stops = {
1022  0.0,
1023  (1.0 / 6.0) * 1,
1024  (1.0 / 6.0) * 2,
1025  (1.0 / 6.0) * 3,
1026  (1.0 / 6.0) * 4,
1027  (1.0 / 6.0) * 5,
1028  1.0,
1029  };
1030  auto texture = CreateTextureForFixture("airplane.jpg",
1031  /*enable_mipmapping=*/true);
1032 
1033  paint.color_source = ColorSource::MakeRadialGradient(
1034  {500, 600}, 75, std::move(gradient_colors), std::move(stops),
1035  Entity::TileMode::kMirror, {});
1036  draw(canvas, {500, 600}, 5, 10, 10);
1037 
1038  paint.color_source = ColorSource::MakeImage(
1039  texture, Entity::TileMode::kRepeat, Entity::TileMode::kRepeat, {},
1040  Matrix::MakeTranslation({700, 200}));
1041  draw(canvas, {800, 300}, 5, 10, 10);
1042 
1043  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1044 }

References impeller::Color::Blue(), impeller::Color::Crimson(), impeller::Canvas::DrawPaint(), impeller::Color::Green(), impeller::Entity::kMirror, impeller::Entity::kRepeat, impeller::Paint::kStroke, impeller::ColorSource::MakeImage(), impeller::ColorSource::MakeRadialGradient(), impeller::Matrix::MakeTranslation(), paint, impeller::Canvas::Scale(), and impeller::Color::White().

◆ TEST_P() [228/456]

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

Definition at line 2838 of file aiks_unittests.cc.

2838  {
2839  Path path = PathBuilder{}
2840  .MoveTo({0, 400})
2841  .LineTo({0, 0})
2842  .LineTo({400, 0})
2843  // MoveTo implicitly adds a contour, ensure that close doesn't
2844  // add another nearly-empty contour.
2845  .MoveTo({0, 400})
2846  .Close()
2847  .TakePath();
2848 
2849  Canvas canvas;
2850  canvas.Translate({50, 50, 0});
2851  canvas.DrawPath(path, {
2852  .color = Color::Blue(),
2853  .stroke_width = 10,
2854  .stroke_cap = Cap::kRound,
2855  .style = Paint::Style::kStroke,
2856  });
2857  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2858 }

References impeller::Color::Blue(), impeller::Close(), impeller::Canvas::DrawPath(), impeller::Canvas::EndRecordingAsPicture(), impeller::kRound, impeller::Paint::kStroke, impeller::LineTo(), impeller::MoveTo(), impeller::PathBuilder::MoveTo(), and impeller::Canvas::Translate().

◆ TEST_P() [229/456]

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

Definition at line 2589 of file aiks_unittests.cc.

2589  {
2590  Canvas canvas;
2591 
2592  // Use a non-srcOver blend mode to ensure that we don't detect this as an
2593  // opacity peephole optimization.
2594  canvas.SaveLayer(
2595  {.color = Color::Blue().WithAlpha(0.5), .blend_mode = BlendMode::kSource},
2596  Rect::MakeLTRB(0, 0, 200, 200));
2597  canvas.DrawPaint(
2598  {.color = Color::BlackTransparent(), .blend_mode = BlendMode::kSource});
2599  canvas.Restore();
2600 
2601  canvas.SaveLayer(
2602  {.color = Color::Blue(), .blend_mode = BlendMode::kDestinationOver});
2603  canvas.Restore();
2604 
2605  // This playground should appear blank on CI since we are only drawing
2606  // transparent black. If the clear color optimization is broken, the texture
2607  // will be filled with NaNs and may produce a magenta texture on macOS or iOS.
2608  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2609 }

References impeller::Color::BlackTransparent(), impeller::Color::Blue(), impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), impeller::kDestinationOver, impeller::kSource, impeller::TRect< Scalar >::MakeLTRB(), impeller::Canvas::Restore(), impeller::Canvas::SaveLayer(), and impeller::Color::WithAlpha().

◆ TEST_P() [230/456]

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

Definition at line 2306 of file aiks_unittests.cc.

2306  {
2307  auto mapping = flutter::testing::OpenFixtureAsSkData("Roboto-Regular.ttf");
2308  ASSERT_NE(mapping, nullptr);
2309 
2310  Scalar font_size = 100;
2311  sk_sp<SkFontMgr> font_mgr = txt::GetDefaultFontManager();
2312  SkFont sk_font(font_mgr->makeFromData(mapping), font_size);
2313 
2314  Paint text_paint;
2315  text_paint.color = Color::Blue();
2316 
2317  std::vector<Color> colors = {Color{0.9568, 0.2627, 0.2118, 1.0},
2318  Color{0.1294, 0.5882, 0.9529, 1.0}};
2319  std::vector<Scalar> stops = {
2320  0.0,
2321  1.0,
2322  };
2323  text_paint.color_source = ColorSource::MakeLinearGradient(
2324  {0, 0}, {100, 100}, std::move(colors), std::move(stops),
2325  Entity::TileMode::kRepeat, {});
2326 
2327  Canvas canvas;
2328  canvas.Translate({100, 100});
2329  canvas.Rotate(Radians(kPi / 4));
2330 
2331  auto blob = SkTextBlob::MakeFromString("Hello", sk_font);
2332  ASSERT_NE(blob, nullptr);
2333  auto frame = MakeTextFrameFromTextBlobSkia(blob);
2334  canvas.DrawTextFrame(frame, Point(), text_paint);
2335 
2336  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2337 }

References impeller::Color::Blue(), impeller::Paint::color, impeller::Paint::color_source, font_size, impeller::kPi, impeller::Entity::kRepeat, impeller::ColorSource::MakeLinearGradient(), impeller::MakeTextFrameFromTextBlobSkia(), and impeller::Canvas::Translate().

◆ TEST_P() [231/456]

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

Definition at line 684 of file aiks_unittests.cc.

684  {
685  // "Random" numbers between 0 and 1. Hardcoded to avoid flakiness in goldens.
686  std::array<Scalar, 20> phase_offsets = {
687  7.82637e-06, 0.131538, 0.755605, 0.45865, 0.532767,
688  0.218959, 0.0470446, 0.678865, 0.679296, 0.934693,
689  0.383502, 0.519416, 0.830965, 0.0345721, 0.0534616,
690  0.5297, 0.671149, 0.00769819, 0.383416, 0.0668422};
691  auto callback = [&](AiksContext& renderer) -> std::optional<Picture> {
692  static float font_size = 20;
693  static float phase_variation = 0.2;
694  static float speed = 0.5;
695  static float magnitude = 100;
696  if (AiksTest::ImGuiBegin("Controls", nullptr,
697  ImGuiWindowFlags_AlwaysAutoResize)) {
698  ImGui::SliderFloat("Font size", &font_size, 5, 50);
699  ImGui::SliderFloat("Phase variation", &phase_variation, 0, 1);
700  ImGui::SliderFloat("Oscillation speed", &speed, 0, 2);
701  ImGui::SliderFloat("Oscillation magnitude", &magnitude, 0, 300);
702  ImGui::End();
703  }
704 
705  Canvas canvas;
706  canvas.Scale(GetContentScale());
707 
708  for (size_t i = 0; i < phase_offsets.size(); i++) {
709  auto position =
710  Point(200 + magnitude *
711  std::sin((-phase_offsets[i] * k2Pi * phase_variation +
712  GetSecondsElapsed() * speed)), //
713  200 + i * font_size * 1.1 //
714  );
716  GetContext(), canvas,
717  "the quick brown fox jumped over "
718  "the lazy dog!.?",
719  "Roboto-Regular.ttf",
720  {.font_size = font_size, .position = position})) {
721  return std::nullopt;
722  }
723  }
724  return canvas.EndRecordingAsPicture();
725  };
726 
727  ASSERT_TRUE(OpenPlaygroundHere(callback));
728 }

References impeller::Canvas::EndRecordingAsPicture(), font_size, impeller::AiksPlayground::ImGuiBegin(), impeller::k2Pi, RenderTextInCanvasSkia(), and impeller::Canvas::Scale().

◆ TEST_P() [232/456]

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

Definition at line 839 of file aiks_unittests.cc.

839  {
840  Canvas canvas;
841  canvas.Scale(GetContentScale());
842  canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)});
843 
844  canvas.Transform(Matrix(0.25, -0.3, 0, -0.002, //
845  0, 0.5, 0, 0, //
846  0, 0, 0.3, 0, //
847  100, 100, 0, 1.3));
848  ASSERT_TRUE(RenderTextInCanvasSkia(
849  GetContext(), canvas, "the quick brown fox jumped over the lazy dog!.?",
850  "Roboto-Regular.ttf"));
851 
852  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
853 }

References impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), RenderTextInCanvasSkia(), impeller::Canvas::Scale(), and impeller::Canvas::Transform().

◆ TEST_P() [233/456]

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

Definition at line 884 of file aiks_unittests.cc.

884  {
885  Canvas canvas;
886  ASSERT_MATRIX_NEAR(canvas.GetCurrentTransform(), Matrix());
887 
888  // clang-format off
889  canvas.Translate(Vector3(100, 200));
891  canvas.GetCurrentTransform(),
892  Matrix( 1, 0, 0, 0,
893  0, 1, 0, 0,
894  0, 0, 1, 0,
895  100, 200, 0, 1));
896 
897  canvas.Rotate(Radians(kPiOver2));
899  canvas.GetCurrentTransform(),
900  Matrix( 0, 1, 0, 0,
901  -1, 0, 0, 0,
902  0, 0, 1, 0,
903  100, 200, 0, 1));
904 
905  canvas.Scale(Vector3(2, 3));
907  canvas.GetCurrentTransform(),
908  Matrix( 0, 2, 0, 0,
909  -3, 0, 0, 0,
910  0, 0, 0, 0,
911  100, 200, 0, 1));
912 
913  canvas.Translate(Vector3(100, 200));
915  canvas.GetCurrentTransform(),
916  Matrix( 0, 2, 0, 0,
917  -3, 0, 0, 0,
918  0, 0, 0, 0,
919  -500, 400, 0, 1));
920  // clang-format on
921 }

References ASSERT_MATRIX_NEAR, impeller::Canvas::GetCurrentTransform(), impeller::kPiOver2, impeller::Canvas::Rotate(), impeller::Canvas::Scale(), and impeller::Canvas::Translate().

◆ TEST_P() [234/456]

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

Definition at line 1848 of file aiks_unittests.cc.

1848  {
1849  Canvas canvas;
1850 
1851  canvas.DrawRect(Rect::MakeXYWH(100, 100, 300, 300), {.color = Color::Blue()});
1852 
1853  canvas.SaveLayer({.color = Color::Black().WithAlpha(0.5)});
1854  canvas.DrawRect(Rect::MakeXYWH(100, 500, 300, 300), {.color = Color::Blue()});
1855  canvas.Restore();
1856 
1857  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1858 }

References impeller::Color::Black(), impeller::Color::Blue(), impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Canvas::Restore(), impeller::Canvas::SaveLayer(), and impeller::Color::WithAlpha().

◆ TEST_P() [235/456]

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

Definition at line 2021 of file aiks_unittests.cc.

2021  {
2022  Canvas canvas;
2023 
2024  auto image = std::make_shared<Image>(CreateTextureForFixture("airplane.jpg"));
2025  canvas.DrawImage(image, {100, 100}, {});
2026 
2027  canvas.SaveLayer({.color = Color::Black().WithAlpha(0.5)});
2028  canvas.DrawImage(image, {100, 500}, {});
2029  canvas.Restore();
2030 
2031  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2032 }

References impeller::Color::Black(), impeller::Canvas::DrawImage(), impeller::Canvas::EndRecordingAsPicture(), impeller::Canvas::Restore(), impeller::Canvas::SaveLayer(), and impeller::Color::WithAlpha().

◆ TEST_P() [236/456]

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

Definition at line 2105 of file aiks_unittests.cc.

2105  {
2106  Canvas canvas;
2107  canvas.DrawRect(Rect::MakeXYWH(0, 0, 400, 400), {.color = Color::Red()});
2108  canvas.SaveLayer({
2109  .color = Color::Black().WithAlpha(0.5),
2110  .blend_mode = BlendMode::kLighten,
2111  });
2112  canvas.DrawCircle({200, 200}, 100, {.color = Color::Green()});
2113  canvas.Restore();
2114  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2115 }

References impeller::Color::Black(), impeller::Canvas::DrawCircle(), impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::Green(), impeller::kLighten, impeller::TRect< Scalar >::MakeXYWH(), impeller::Color::Red(), impeller::Canvas::Restore(), impeller::Canvas::SaveLayer(), and impeller::Color::WithAlpha().

◆ TEST_P() [237/456]

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

Definition at line 1860 of file aiks_unittests.cc.

1860  {
1861  Canvas canvas;
1862 
1863  canvas.DrawRect(Rect::MakeXYWH(100, 100, 300, 300), {.color = Color::Blue()});
1864 
1865  canvas.SaveLayer({
1866  .color = Color::Black().WithAlpha(0.5),
1867  .color_filter =
1868  ColorFilter::MakeBlend(BlendMode::kDestinationOver, Color::Red()),
1869  });
1870  canvas.DrawRect(Rect::MakeXYWH(100, 500, 300, 300), {.color = Color::Blue()});
1871  canvas.Restore();
1872 
1873  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1874 }

References impeller::Color::Black(), impeller::Color::Blue(), impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::kDestinationOver, impeller::ColorFilter::MakeBlend(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Color::Red(), impeller::Canvas::Restore(), impeller::Canvas::SaveLayer(), and impeller::Color::WithAlpha().

◆ TEST_P() [238/456]

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

Definition at line 1876 of file aiks_unittests.cc.

1876  {
1877  Canvas canvas;
1878 
1879  canvas.DrawRect(Rect::MakeXYWH(100, 100, 300, 300), {.color = Color::Blue()});
1880 
1881  canvas.SaveLayer({
1882  .color = Color::Black().WithAlpha(0.5),
1883  .image_filter = ImageFilter::MakeFromColorFilter(
1884  *ColorFilter::MakeBlend(BlendMode::kDestinationOver, Color::Red())),
1885  });
1886 
1887  canvas.DrawRect(Rect::MakeXYWH(100, 500, 300, 300), {.color = Color::Blue()});
1888  canvas.Restore();
1889 
1890  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1891 }

References impeller::Color::Black(), impeller::Color::Blue(), impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::kDestinationOver, impeller::ColorFilter::MakeBlend(), impeller::ImageFilter::MakeFromColorFilter(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Color::Red(), impeller::Canvas::Restore(), impeller::Canvas::SaveLayer(), and impeller::Color::WithAlpha().

◆ TEST_P() [239/456]

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

Definition at line 1893 of file aiks_unittests.cc.

1893  {
1894  Canvas canvas;
1895 
1896  canvas.DrawRect(Rect::MakeXYWH(100, 100, 300, 300), {.color = Color::Blue()});
1897 
1898  canvas.SaveLayer({
1899  .color = Color::Black().WithAlpha(0.5),
1900  .color_filter =
1901  ColorFilter::MakeBlend(BlendMode::kDestinationOver, Color::Red()),
1902  });
1903 
1904  canvas.DrawRect(Rect::MakeXYWH(100, 500, 300, 300), {.color = Color::Blue()});
1905  canvas.Restore();
1906 
1907  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1908 }

References impeller::Color::Black(), impeller::Color::Blue(), impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::kDestinationOver, impeller::ColorFilter::MakeBlend(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Color::Red(), impeller::Canvas::Restore(), impeller::Canvas::SaveLayer(), and impeller::Color::WithAlpha().

◆ TEST_P() [240/456]

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

Definition at line 2079 of file aiks_unittests.cc.

2080  {
2081  Canvas canvas;
2082 
2083  auto image = std::make_shared<Image>(CreateTextureForFixture("airplane.jpg"));
2084  canvas.DrawImage(image, {100, 100}, {});
2085 
2086  canvas.SaveLayer({
2087  .color = Color::Black().WithAlpha(0.5),
2088  .image_filter = ImageFilter::MakeFromColorFilter(
2089  *ColorFilter::MakeMatrix({.array =
2090  {
2091  1, 0, 0, 0, 0, //
2092  0, 1, 0, 0, 0, //
2093  0, 0.2, 1, 0, 0, //
2094  0, 0, 0, 0.5, 0 //
2095  }})),
2096  .color_filter =
2097  ColorFilter::MakeBlend(BlendMode::kModulate, Color::Green()),
2098  });
2099  canvas.DrawImage(image, {100, 500}, {});
2100  canvas.Restore();
2101 
2102  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2103 }

References impeller::Color::Black(), impeller::Canvas::DrawImage(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::Green(), impeller::kModulate, impeller::ColorFilter::MakeBlend(), impeller::ImageFilter::MakeFromColorFilter(), impeller::ColorFilter::MakeMatrix(), impeller::Canvas::Restore(), impeller::Canvas::SaveLayer(), and impeller::Color::WithAlpha().

◆ TEST_P() [241/456]

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

Definition at line 2034 of file aiks_unittests.cc.

2034  {
2035  Canvas canvas;
2036 
2037  auto image = std::make_shared<Image>(CreateTextureForFixture("airplane.jpg"));
2038  canvas.DrawImage(image, {100, 100}, {});
2039 
2040  canvas.SaveLayer({
2041  .color = Color::Black().WithAlpha(0.5),
2042  .color_filter = ColorFilter::MakeMatrix({.array =
2043  {
2044  1, 0, 0, 0, 0, //
2045  0, 1, 0, 0, 0, //
2046  0, 0, 1, 0, 0, //
2047  0, 0, 0, 2, 0 //
2048  }}),
2049  });
2050  canvas.DrawImage(image, {100, 500}, {});
2051  canvas.Restore();
2052 
2053  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2054 }

References impeller::Color::Black(), impeller::Canvas::DrawImage(), impeller::Canvas::EndRecordingAsPicture(), impeller::ColorFilter::MakeMatrix(), impeller::Canvas::Restore(), impeller::Canvas::SaveLayer(), and impeller::Color::WithAlpha().

◆ TEST_P() [242/456]

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

Definition at line 2056 of file aiks_unittests.cc.

2056  {
2057  Canvas canvas;
2058 
2059  auto image = std::make_shared<Image>(CreateTextureForFixture("airplane.jpg"));
2060  canvas.DrawImage(image, {100, 100}, {});
2061 
2062  canvas.SaveLayer({
2063  .color = Color::Black().WithAlpha(0.5),
2064  .image_filter = ImageFilter::MakeFromColorFilter(
2065  *ColorFilter::MakeMatrix({.array =
2066  {
2067  1, 0, 0, 0, 0, //
2068  0, 1, 0, 0, 0, //
2069  0, 0, 1, 0, 0, //
2070  0, 0, 0, 2, 0 //
2071  }})),
2072  });
2073  canvas.DrawImage(image, {100, 500}, {});
2074  canvas.Restore();
2075 
2076  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2077 }

References impeller::Color::Black(), impeller::Canvas::DrawImage(), impeller::Canvas::EndRecordingAsPicture(), impeller::ImageFilter::MakeFromColorFilter(), impeller::ColorFilter::MakeMatrix(), impeller::Canvas::Restore(), impeller::Canvas::SaveLayer(), and impeller::Color::WithAlpha().

◆ TEST_P() [243/456]

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

Definition at line 807 of file aiks_dl_gradient_unittests.cc.

807  {
808  DisplayListBuilder builder;
809  DlPaint paint;
810  builder.Translate(100.0f, 0);
811 
812  std::vector<DlColor> colors = {DlColor::kRed(), DlColor::kBlue(),
813  DlColor::kGreen()};
814  std::vector<Scalar> stops = {0.0, 0.1, 1.0};
815 
816  // Inset the start and end point to verify that we do not apply
817  // the fast gradient condition.
818  paint.setColorSource(
819  DlColorSource::MakeLinear({0, 150}, {0, 100}, stops.size(), colors.data(),
820  stops.data(), DlTileMode::kRepeat));
821 
822  paint.setColor(DlColor::kWhite());
823  builder.DrawRect(SkRect::MakeXYWH(0, 0, 300, 300), paint);
824  builder.Translate(400, 0);
825  builder.DrawRRect(SkRRect::MakeRectXY(SkRect::MakeXYWH(0, 0, 300, 300), 4, 4),
826  paint);
827 
828  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
829 }

References paint.

◆ TEST_P() [244/456]

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

Definition at line 93 of file aiks_dl_vertices_unittests.cc.

93  {
94  DisplayListBuilder builder;
95  DlPaint paint;
96  auto image =
97  DlImageImpeller::Make(CreateTextureForFixture("table_mountain_nx.png"));
98  auto size = image->impeller_texture()->GetSize();
99 
100  paint.setColorSource(std::make_shared<DlImageColorSource>(
101  image, DlTileMode::kClamp, DlTileMode::kClamp));
102 
103  std::vector<SkPoint> positions = {
104  SkPoint::Make(0, 0), SkPoint::Make(size.width, 0),
105  SkPoint::Make(0, size.height), SkPoint::Make(size.width, 0),
106  SkPoint::Make(0, 0), SkPoint::Make(size.width, size.height),
107  };
108  std::vector<DlColor> colors = {
109  DlColor::kRed().withAlpha(128), DlColor::kBlue().withAlpha(128),
110  DlColor::kGreen().withAlpha(128), DlColor::kRed().withAlpha(128),
111  DlColor::kBlue().withAlpha(128), DlColor::kGreen().withAlpha(128),
112  };
113 
114  auto vertices =
115  MakeVertices(DlVertexMode::kTriangles, positions, {}, {}, colors);
116 
117  builder.DrawVertices(vertices, DlBlendMode::kDstOver, paint);
118  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
119 }

References impeller::DlImageImpeller::Make(), impeller::MakeVertices(), and paint.

◆ TEST_P() [245/456]

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

Definition at line 121 of file aiks_dl_vertices_unittests.cc.

121  {
122  DisplayListBuilder builder;
123  DlPaint paint;
124  auto image =
125  DlImageImpeller::Make(CreateTextureForFixture("table_mountain_nx.png"));
126  auto size = image->impeller_texture()->GetSize();
127 
128  paint.setColorSource(std::make_shared<DlImageColorSource>(
129  image, DlTileMode::kClamp, DlTileMode::kClamp));
130 
131  std::vector<SkPoint> positions = {
132  SkPoint::Make(0, 0), SkPoint::Make(size.width, 0),
133  SkPoint::Make(0, size.height), SkPoint::Make(size.width, 0),
134  SkPoint::Make(0, 0), SkPoint::Make(size.width, size.height),
135  };
136  std::vector<DlColor> colors = {
137  DlColor::kRed().modulateOpacity(0.5),
138  DlColor::kBlue().modulateOpacity(0.5),
139  DlColor::kGreen().modulateOpacity(0.5),
140  DlColor::kRed().modulateOpacity(0.5),
141  DlColor::kBlue().modulateOpacity(0.5),
142  DlColor::kGreen().modulateOpacity(0.5),
143  };
144 
145  auto vertices =
146  MakeVertices(DlVertexMode::kTriangles, positions, {}, {}, colors);
147 
148  builder.DrawVertices(vertices, DlBlendMode::kColorBurn, paint);
149  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
150 }

References impeller::DlImageImpeller::Make(), impeller::MakeVertices(), and paint.

◆ TEST_P() [246/456]

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

Definition at line 47 of file aiks_dl_vertices_unittests.cc.

47  {
48  DisplayListBuilder builder;
49  DlPaint paint;
50  auto image =
51  DlImageImpeller::Make(CreateTextureForFixture("table_mountain_nx.png"));
52  auto size = image->impeller_texture()->GetSize();
53 
54  paint.setColorSource(std::make_shared<DlImageColorSource>(
55  image, DlTileMode::kClamp, DlTileMode::kClamp));
56 
57  std::vector<SkPoint> vertex_coordinates = {SkPoint::Make(0, 0),
58  SkPoint::Make(size.width, 0),
59  SkPoint::Make(0, size.height)};
60  auto vertices = MakeVertices(DlVertexMode::kTriangleStrip, vertex_coordinates,
61  {0, 1, 2}, {}, {});
62 
63  builder.DrawVertices(vertices, DlBlendMode::kSrcOver, paint);
64  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
65 }

References impeller::DlImageImpeller::Make(), impeller::MakeVertices(), and paint.

◆ TEST_P() [247/456]

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

Definition at line 68 of file aiks_dl_vertices_unittests.cc.

68  {
69  DisplayListBuilder builder;
70  DlPaint paint;
71  auto image =
72  DlImageImpeller::Make(CreateTextureForFixture("table_mountain_nx.png"));
73  auto size = image->impeller_texture()->GetSize();
74 
75  SkMatrix matrix;
76  matrix.setTranslateX(100);
77  matrix.setTranslateY(100);
78  paint.setColorSource(std::make_shared<DlImageColorSource>(
79  image, DlTileMode::kClamp, DlTileMode::kClamp, DlImageSampling::kLinear,
80  &matrix));
81 
82  std::vector<SkPoint> positions = {SkPoint::Make(0, 0),
83  SkPoint::Make(size.width, 0),
84  SkPoint::Make(0, size.height)};
85  auto vertices =
86  MakeVertices(DlVertexMode::kTriangleStrip, positions, {0, 1, 2}, {}, {});
87 
88  builder.DrawVertices(vertices, DlBlendMode::kSrcOver, paint);
89  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
90 }

References impeller::DlImageImpeller::Make(), impeller::MakeVertices(), and paint.

◆ TEST_P() [248/456]

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(), 0u);
33 
34  // Memoryless texture does not increase allocated size.
35  {
36  TextureDescriptor desc;
37  desc.format = PixelFormat::kR8G8B8A8UNormInt;
38  desc.storage_mode = StorageMode::kDeviceTransient;
39  desc.size = {1024, 1024};
40  auto texture_1 = allocator->CreateTexture(desc);
41 
42  EXPECT_EQ(allocator->DebugGetHeapUsage(), 0u);
43 
44  // Private storage texture increases allocated size.
45  desc.storage_mode = StorageMode::kDevicePrivate;
46  auto texture_2 = allocator->CreateTexture(desc);
47 
48 #ifdef IMPELLER_DEBUG
49  EXPECT_EQ(allocator->DebugGetHeapUsage(), 4u);
50 #else
51  EXPECT_EQ(allocator->DebugGetHeapUsage(), 0u);
52 #endif // IMPELLER_DEBUG
53 
54  // Host storage texture increases allocated size.
55  desc.storage_mode = StorageMode::kHostVisible;
56  auto texture_3 = allocator->CreateTexture(desc);
57 
58 #ifdef IMPELLER_DEBUG
59  EXPECT_EQ(allocator->DebugGetHeapUsage(), 8u);
60 #else
61  EXPECT_EQ(allocator->DebugGetHeapUsage(), 0u);
62 #endif // IMPELLER_DEBUG
63  }
64 
65  // After all textures are out of scope, memory has been decremented.
66  EXPECT_EQ(allocator->DebugGetHeapUsage(), 0u);
67 }

References impeller::BackendCast< ContextMTL, Context >::Cast(), impeller::TextureDescriptor::format, impeller::kDevicePrivate, impeller::kDeviceTransient, impeller::kHostVisible, impeller::kR8G8B8A8UNormInt, impeller::TextureDescriptor::size, and impeller::TextureDescriptor::storage_mode.

◆ TEST_P() [249/456]

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.range.offset, 4u);
58  EXPECT_EQ(buffer_view.range.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() [250/456]

impeller::testing::TEST_P ( BlitPassTest  ,
BlitAcrossDifferentPixelFormatsFails   
)

Definition at line 19 of file blit_pass_unittests.cc.

19  {
20  ScopedValidationDisable scope; // avoid noise in output.
21  auto context = GetContext();
22  auto cmd_buffer = context->CreateCommandBuffer();
23  auto blit_pass = cmd_buffer->CreateBlitPass();
24 
25  TextureDescriptor src_desc;
26  src_desc.format = PixelFormat::kA8UNormInt;
27  src_desc.size = {100, 100};
28  src_desc.storage_mode = StorageMode::kHostVisible;
29  auto src = context->GetResourceAllocator()->CreateTexture(src_desc);
30 
31  TextureDescriptor dst_format;
32  dst_format.format = PixelFormat::kR8G8B8A8UNormInt;
33  dst_format.size = {100, 100};
34  dst_format.storage_mode = StorageMode::kHostVisible;
35  auto dst = context->GetResourceAllocator()->CreateTexture(dst_format);
36 
37  EXPECT_FALSE(blit_pass->AddCopy(src, dst));
38 }

References impeller::TextureDescriptor::format, impeller::kA8UNormInt, impeller::kHostVisible, impeller::kR8G8B8A8UNormInt, impeller::TextureDescriptor::size, and impeller::TextureDescriptor::storage_mode.

◆ TEST_P() [251/456]

impeller::testing::TEST_P ( BlitPassTest  ,
BlitAcrossDifferentSampleCountsFails   
)

Definition at line 40 of file blit_pass_unittests.cc.

40  {
41  ScopedValidationDisable scope; // avoid noise in output.
42  auto context = GetContext();
43  auto cmd_buffer = context->CreateCommandBuffer();
44  auto blit_pass = cmd_buffer->CreateBlitPass();
45 
46  TextureDescriptor src_desc;
47  src_desc.format = PixelFormat::kR8G8B8A8UNormInt;
48  src_desc.sample_count = SampleCount::kCount4;
49  src_desc.size = {100, 100};
50  auto src = context->GetResourceAllocator()->CreateTexture(src_desc);
51 
52  TextureDescriptor dst_format;
53  dst_format.format = PixelFormat::kR8G8B8A8UNormInt;
54  dst_format.size = {100, 100};
55  auto dst = context->GetResourceAllocator()->CreateTexture(dst_format);
56 
57  EXPECT_FALSE(blit_pass->AddCopy(src, dst));
58 }

References impeller::TextureDescriptor::format, impeller::kCount4, impeller::kR8G8B8A8UNormInt, impeller::TextureDescriptor::sample_count, and impeller::TextureDescriptor::size.

◆ TEST_P() [252/456]

impeller::testing::TEST_P ( BlitPassTest  ,
BlitPassesForMatchingFormats   
)

Definition at line 60 of file blit_pass_unittests.cc.

60  {
61  ScopedValidationDisable scope; // avoid noise in output.
62  auto context = GetContext();
63  auto cmd_buffer = context->CreateCommandBuffer();
64  auto blit_pass = cmd_buffer->CreateBlitPass();
65 
66  TextureDescriptor src_desc;
67  src_desc.format = PixelFormat::kR8G8B8A8UNormInt;
68  src_desc.size = {100, 100};
69  src_desc.storage_mode = StorageMode::kHostVisible;
70  auto src = context->GetResourceAllocator()->CreateTexture(src_desc);
71 
72  TextureDescriptor dst_format;
73  dst_format.format = PixelFormat::kR8G8B8A8UNormInt;
74  dst_format.size = {100, 100};
75  dst_format.storage_mode = StorageMode::kHostVisible;
76  auto dst = context->GetResourceAllocator()->CreateTexture(dst_format);
77 
78  EXPECT_TRUE(blit_pass->AddCopy(src, dst));
79 }

References impeller::TextureDescriptor::format, impeller::kHostVisible, impeller::kR8G8B8A8UNormInt, impeller::TextureDescriptor::size, and impeller::TextureDescriptor::storage_mode.

◆ TEST_P() [253/456]

impeller::testing::TEST_P ( BlitPassTest  ,
CanBlitSmallRegionToUninitializedTexture   
)

Definition at line 109 of file blit_pass_unittests.cc.

109  {
110  auto context = GetContext();
111  auto cmd_buffer = context->CreateCommandBuffer();
112  auto blit_pass = cmd_buffer->CreateBlitPass();
113 
114  TextureDescriptor dst_format;
115  dst_format.storage_mode = StorageMode::kDevicePrivate;
116  dst_format.format = PixelFormat::kR8G8B8A8UNormInt;
117  dst_format.size = {1000, 1000};
118  auto dst = context->GetResourceAllocator()->CreateTexture(dst_format);
119 
120  DeviceBufferDescriptor src_format;
121  src_format.size = 4;
122  src_format.storage_mode = StorageMode::kHostVisible;
123  auto src = context->GetResourceAllocator()->CreateBuffer(src_format);
124 
125  ASSERT_TRUE(dst);
126 
127  EXPECT_TRUE(blit_pass->AddCopy(DeviceBuffer::AsBufferView(src), dst,
128  IRect::MakeLTRB(0, 0, 1, 1), "", /*slice=*/0));
129  EXPECT_TRUE(blit_pass->EncodeCommands(GetContext()->GetResourceAllocator()));
130  EXPECT_TRUE(context->GetCommandQueue()->Submit({std::move(cmd_buffer)}).ok());
131 }

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

impeller::testing::TEST_P ( BlitPassTest  ,
ChecksInvalidSliceParameters   
)

Definition at line 81 of file blit_pass_unittests.cc.

81  {
82  ScopedValidationDisable scope; // avoid noise in output.
83  auto context = GetContext();
84  auto cmd_buffer = context->CreateCommandBuffer();
85  auto blit_pass = cmd_buffer->CreateBlitPass();
86 
87  TextureDescriptor dst_format;
88  dst_format.storage_mode = StorageMode::kDevicePrivate;
89  dst_format.format = PixelFormat::kR8G8B8A8UNormInt;
90  dst_format.size = {100, 100};
91  auto dst = context->GetResourceAllocator()->CreateTexture(dst_format);
92 
93  DeviceBufferDescriptor src_format;
94  src_format.size = 40000;
95  src_format.storage_mode = StorageMode::kHostVisible;
96  auto src = context->GetResourceAllocator()->CreateBuffer(src_format);
97 
98  ASSERT_TRUE(dst);
99  ASSERT_TRUE(src);
100 
101  EXPECT_FALSE(blit_pass->AddCopy(DeviceBuffer::AsBufferView(src), dst,
102  std::nullopt, "", /*slice=*/25));
103  EXPECT_FALSE(blit_pass->AddCopy(DeviceBuffer::AsBufferView(src), dst,
104  std::nullopt, "", /*slice=*/6));
105  EXPECT_TRUE(blit_pass->AddCopy(DeviceBuffer::AsBufferView(src), dst,
106  std::nullopt, "", /*slice=*/0));
107 }

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

impeller::testing::TEST_P ( ComputeTest  ,
1DThreadgroupSizingIsCorrect   
)

Definition at line 175 of file compute_unittests.cc.

175  {
176  using CS = ThreadgroupSizingTestComputeShader;
177  auto context = GetContext();
178  ASSERT_TRUE(context);
179  ASSERT_TRUE(context->GetCapabilities()->SupportsCompute());
180 
181  using SamplePipelineBuilder = ComputePipelineBuilder<CS>;
182  auto pipeline_desc =
183  SamplePipelineBuilder::MakeDefaultPipelineDescriptor(*context);
184  ASSERT_TRUE(pipeline_desc.has_value());
185  auto compute_pipeline =
186  context->GetPipelineLibrary()->GetPipeline(pipeline_desc).Get();
187  ASSERT_TRUE(compute_pipeline);
188 
189  auto cmd_buffer = context->CreateCommandBuffer();
190  auto pass = cmd_buffer->CreateComputePass();
191  ASSERT_TRUE(pass && pass->IsValid());
192 
193  static constexpr size_t kCount = 2048;
194 
195  pass->SetPipeline(compute_pipeline);
196 
197  auto output_buffer = CreateHostVisibleDeviceBuffer<CS::OutputData<kCount>>(
198  context, "Output Buffer");
199 
200  CS::BindOutputData(*pass, DeviceBuffer::AsBufferView(output_buffer));
201 
202  ASSERT_TRUE(pass->Compute(ISize(kCount, 1)).ok());
203  ASSERT_TRUE(pass->EncodeCommands());
204 
205  fml::AutoResetWaitableEvent latch;
206  ASSERT_TRUE(
207  context->GetCommandQueue()
208  ->Submit({cmd_buffer},
209  [&latch, output_buffer](CommandBuffer::Status status) {
210  EXPECT_EQ(status, CommandBuffer::Status::kCompleted);
211 
212  auto view = DeviceBuffer::AsBufferView(output_buffer);
213  EXPECT_EQ(view.range.length,
214  sizeof(CS::OutputData<kCount>));
215 
216  CS::OutputData<kCount>* output =
217  reinterpret_cast<CS::OutputData<kCount>*>(
218  output_buffer->OnGetContents());
219  EXPECT_TRUE(output);
220  EXPECT_EQ(output->data[kCount - 1], kCount - 1);
221  latch.Signal();
222  })
223  .ok());
224 
225  latch.Wait();
226 }

◆ TEST_P() [256/456]

impeller::testing::TEST_P ( ComputeTest  ,
CanCompute1DimensionalData   
)

Definition at line 373 of file compute_unittests.cc.

373  {
374  using CS = SampleComputeShader;
375  auto context = GetContext();
376  auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
377  ASSERT_TRUE(context);
378  ASSERT_TRUE(context->GetCapabilities()->SupportsCompute());
379 
380  using SamplePipelineBuilder = ComputePipelineBuilder<CS>;
381  auto pipeline_desc =
382  SamplePipelineBuilder::MakeDefaultPipelineDescriptor(*context);
383  ASSERT_TRUE(pipeline_desc.has_value());
384  auto compute_pipeline =
385  context->GetPipelineLibrary()->GetPipeline(pipeline_desc).Get();
386  ASSERT_TRUE(compute_pipeline);
387 
388  auto cmd_buffer = context->CreateCommandBuffer();
389  auto pass = cmd_buffer->CreateComputePass();
390  ASSERT_TRUE(pass && pass->IsValid());
391 
392  static constexpr size_t kCount = 5;
393 
394  pass->SetPipeline(compute_pipeline);
395 
396  CS::Info info{.count = kCount};
397  CS::Input0<kCount> input_0;
398  CS::Input1<kCount> input_1;
399  for (size_t i = 0; i < kCount; i++) {
400  input_0.elements[i] = Vector4(2.0 + i, 3.0 + i, 4.0 + i, 5.0 * i);
401  input_1.elements[i] = Vector4(6.0, 7.0, 8.0, 9.0);
402  }
403 
404  input_0.fixed_array[1] = IPoint32(2, 2);
405  input_1.fixed_array[0] = UintPoint32(3, 3);
406  input_0.some_int = 5;
407  input_1.some_struct = CS::SomeStruct{.vf = Point(3, 4), .i = 42};
408 
409  auto output_buffer = CreateHostVisibleDeviceBuffer<CS::Output<kCount>>(
410  context, "Output Buffer");
411 
412  CS::BindInfo(*pass, host_buffer->EmplaceUniform(info));
413  CS::BindInput0(*pass, host_buffer->EmplaceStorageBuffer(input_0));
414  CS::BindInput1(*pass, host_buffer->EmplaceStorageBuffer(input_1));
415  CS::BindOutput(*pass, DeviceBuffer::AsBufferView(output_buffer));
416 
417  ASSERT_TRUE(pass->Compute(ISize(kCount, 1)).ok());
418  ASSERT_TRUE(pass->EncodeCommands());
419 
420  fml::AutoResetWaitableEvent latch;
421  ASSERT_TRUE(
422  context->GetCommandQueue()
423  ->Submit(
424  {cmd_buffer},
425  [&latch, output_buffer, &input_0,
426  &input_1](CommandBuffer::Status status) {
427  EXPECT_EQ(status, CommandBuffer::Status::kCompleted);
428 
429  auto view = DeviceBuffer::AsBufferView(output_buffer);
430  EXPECT_EQ(view.range.length, sizeof(CS::Output<kCount>));
431 
432  CS::Output<kCount>* output =
433  reinterpret_cast<CS::Output<kCount>*>(
434  output_buffer->OnGetContents());
435  EXPECT_TRUE(output);
436  for (size_t i = 0; i < kCount; i++) {
437  Vector4 vector = output->elements[i];
438  Vector4 computed = input_0.elements[i] * input_1.elements[i];
439  EXPECT_EQ(vector,
440  Vector4(computed.x + 2 + input_1.some_struct.i,
441  computed.y + 3 + input_1.some_struct.vf.x,
442  computed.z + 5 + input_1.some_struct.vf.y,
443  computed.w));
444  }
445  latch.Signal();
446  })
447  .ok());
448 
449  latch.Wait();
450 }

◆ TEST_P() [257/456]

impeller::testing::TEST_P ( ComputeTest  ,
CanComputePrefixSum   
)

Definition at line 109 of file compute_unittests.cc.

109  {
110  using CS = PrefixSumTestComputeShader;
111  auto context = GetContext();
112  auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
113  ASSERT_TRUE(context);
114  ASSERT_TRUE(context->GetCapabilities()->SupportsCompute());
115 
116  using SamplePipelineBuilder = ComputePipelineBuilder<CS>;
117  auto pipeline_desc =
118  SamplePipelineBuilder::MakeDefaultPipelineDescriptor(*context);
119  ASSERT_TRUE(pipeline_desc.has_value());
120  auto compute_pipeline =
121  context->GetPipelineLibrary()->GetPipeline(pipeline_desc).Get();
122  ASSERT_TRUE(compute_pipeline);
123 
124  auto cmd_buffer = context->CreateCommandBuffer();
125  auto pass = cmd_buffer->CreateComputePass();
126  ASSERT_TRUE(pass && pass->IsValid());
127 
128  static constexpr size_t kCount = 5;
129 
130  pass->SetPipeline(compute_pipeline);
131 
132  CS::InputData<kCount> input_data;
133  input_data.count = kCount;
134  for (size_t i = 0; i < kCount; i++) {
135  input_data.data[i] = 1 + i;
136  }
137 
138  auto output_buffer = CreateHostVisibleDeviceBuffer<CS::OutputData<kCount>>(
139  context, "Output Buffer");
140 
141  CS::BindInputData(*pass, host_buffer->EmplaceStorageBuffer(input_data));
142  CS::BindOutputData(*pass, DeviceBuffer::AsBufferView(output_buffer));
143 
144  ASSERT_TRUE(pass->Compute(ISize(kCount, 1)).ok());
145  ASSERT_TRUE(pass->EncodeCommands());
146 
147  fml::AutoResetWaitableEvent latch;
148  ASSERT_TRUE(
149  context->GetCommandQueue()
150  ->Submit({cmd_buffer},
151  [&latch, output_buffer](CommandBuffer::Status status) {
152  EXPECT_EQ(status, CommandBuffer::Status::kCompleted);
153 
154  auto view = DeviceBuffer::AsBufferView(output_buffer);
155  EXPECT_EQ(view.range.length,
156  sizeof(CS::OutputData<kCount>));
157 
158  CS::OutputData<kCount>* output =
159  reinterpret_cast<CS::OutputData<kCount>*>(
160  output_buffer->OnGetContents());
161  EXPECT_TRUE(output);
162 
163  constexpr uint32_t expected[kCount] = {1, 3, 6, 10, 15};
164  for (size_t i = 0; i < kCount; i++) {
165  auto computed_sum = output->data[i];
166  EXPECT_EQ(computed_sum, expected[i]);
167  }
168  latch.Signal();
169  })
170  .ok());
171 
172  latch.Wait();
173 }

References impeller::DeviceBuffer::AsBufferView(), and impeller::HostBuffer::Create().

◆ TEST_P() [258/456]

impeller::testing::TEST_P ( ComputeTest  ,
CanComputePrefixSumLargeInteractive   
)

Definition at line 228 of file compute_unittests.cc.

228  {
229  using CS = PrefixSumTestComputeShader;
230 
231  auto context = GetContext();
232  auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
233 
234  ASSERT_TRUE(context);
235  ASSERT_TRUE(context->GetCapabilities()->SupportsCompute());
236 
237  auto callback = [&](RenderPass& render_pass) -> bool {
238  using SamplePipelineBuilder = ComputePipelineBuilder<CS>;
239  auto pipeline_desc =
240  SamplePipelineBuilder::MakeDefaultPipelineDescriptor(*context);
241  auto compute_pipeline =
242  context->GetPipelineLibrary()->GetPipeline(pipeline_desc).Get();
243 
244  auto cmd_buffer = context->CreateCommandBuffer();
245  auto pass = cmd_buffer->CreateComputePass();
246 
247  static constexpr size_t kCount = 1023;
248 
249  pass->SetPipeline(compute_pipeline);
250 
251  CS::InputData<kCount> input_data;
252  input_data.count = kCount;
253  for (size_t i = 0; i < kCount; i++) {
254  input_data.data[i] = 1 + i;
255  }
256 
257  auto output_buffer = CreateHostVisibleDeviceBuffer<CS::OutputData<kCount>>(
258  context, "Output Buffer");
259 
260  CS::BindInputData(*pass, host_buffer->EmplaceStorageBuffer(input_data));
261  CS::BindOutputData(*pass, DeviceBuffer::AsBufferView(output_buffer));
262 
263  pass->Compute(ISize(kCount, 1));
264  pass->EncodeCommands();
265  host_buffer->Reset();
266  return context->GetCommandQueue()->Submit({cmd_buffer}).ok();
267  };
268  ASSERT_TRUE(OpenPlaygroundHere(callback));
269 }

◆ TEST_P() [259/456]

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  ASSERT_TRUE(context);
35  ASSERT_TRUE(context->GetCapabilities()->SupportsCompute());
36 
37  using SamplePipelineBuilder = ComputePipelineBuilder<CS>;
38  auto pipeline_desc =
39  SamplePipelineBuilder::MakeDefaultPipelineDescriptor(*context);
40  ASSERT_TRUE(pipeline_desc.has_value());
41  auto compute_pipeline =
42  context->GetPipelineLibrary()->GetPipeline(pipeline_desc).Get();
43  ASSERT_TRUE(compute_pipeline);
44 
45  auto cmd_buffer = context->CreateCommandBuffer();
46  auto pass = cmd_buffer->CreateComputePass();
47  ASSERT_TRUE(pass && pass->IsValid());
48 
49  static constexpr size_t kCount = 5;
50 
51  pass->SetPipeline(compute_pipeline);
52 
53  CS::Info info{.count = kCount};
54  CS::Input0<kCount> input_0;
55  CS::Input1<kCount> input_1;
56  for (size_t i = 0; i < kCount; i++) {
57  input_0.elements[i] = Vector4(2.0 + i, 3.0 + i, 4.0 + i, 5.0 * i);
58  input_1.elements[i] = Vector4(6.0, 7.0, 8.0, 9.0);
59  }
60 
61  input_0.fixed_array[1] = IPoint32(2, 2);
62  input_1.fixed_array[0] = UintPoint32(3, 3);
63  input_0.some_int = 5;
64  input_1.some_struct = CS::SomeStruct{.vf = Point(3, 4), .i = 42};
65 
66  auto output_buffer = CreateHostVisibleDeviceBuffer<CS::Output<kCount>>(
67  context, "Output Buffer");
68 
69  CS::BindInfo(*pass, host_buffer->EmplaceUniform(info));
70  CS::BindInput0(*pass, host_buffer->EmplaceStorageBuffer(input_0));
71  CS::BindInput1(*pass, host_buffer->EmplaceStorageBuffer(input_1));
72  CS::BindOutput(*pass, DeviceBuffer::AsBufferView(output_buffer));
73 
74  ASSERT_TRUE(pass->Compute(ISize(kCount, 1)).ok());
75  ASSERT_TRUE(pass->EncodeCommands());
76 
77  fml::AutoResetWaitableEvent latch;
78  ASSERT_TRUE(
79  context->GetCommandQueue()
80  ->Submit(
81  {cmd_buffer},
82  [&latch, output_buffer, &input_0,
83  &input_1](CommandBuffer::Status status) {
84  EXPECT_EQ(status, CommandBuffer::Status::kCompleted);
85 
86  auto view = DeviceBuffer::AsBufferView(output_buffer);
87  EXPECT_EQ(view.range.length, sizeof(CS::Output<kCount>));
88 
89  CS::Output<kCount>* output =
90  reinterpret_cast<CS::Output<kCount>*>(
91  output_buffer->OnGetContents());
92  EXPECT_TRUE(output);
93  for (size_t i = 0; i < kCount; i++) {
94  Vector4 vector = output->elements[i];
95  Vector4 computed = input_0.elements[i] * input_1.elements[i];
96  EXPECT_EQ(vector,
97  Vector4(computed.x + 2 + input_1.some_struct.i,
98  computed.y + 3 + input_1.some_struct.vf.x,
99  computed.z + 5 + input_1.some_struct.vf.y,
100  computed.w));
101  }
102  latch.Signal();
103  })
104  .ok());
105 
106  latch.Wait();
107 }

References impeller::DeviceBuffer::AsBufferView(), and impeller::HostBuffer::Create().

◆ TEST_P() [260/456]

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

impeller::testing::TEST_P ( ComputeTest  ,
MultiStageInputAndOutput   
)

Definition at line 271 of file compute_unittests.cc.

271  {
272  using CS1 = Stage1ComputeShader;
273  using Stage1PipelineBuilder = ComputePipelineBuilder<CS1>;
274  using CS2 = Stage2ComputeShader;
275  using Stage2PipelineBuilder = ComputePipelineBuilder<CS2>;
276 
277  auto context = GetContext();
278  auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
279  ASSERT_TRUE(context);
280  ASSERT_TRUE(context->GetCapabilities()->SupportsCompute());
281 
282  auto pipeline_desc_1 =
283  Stage1PipelineBuilder::MakeDefaultPipelineDescriptor(*context);
284  ASSERT_TRUE(pipeline_desc_1.has_value());
285  auto compute_pipeline_1 =
286  context->GetPipelineLibrary()->GetPipeline(pipeline_desc_1).Get();
287  ASSERT_TRUE(compute_pipeline_1);
288 
289  auto pipeline_desc_2 =
290  Stage2PipelineBuilder::MakeDefaultPipelineDescriptor(*context);
291  ASSERT_TRUE(pipeline_desc_2.has_value());
292  auto compute_pipeline_2 =
293  context->GetPipelineLibrary()->GetPipeline(pipeline_desc_2).Get();
294  ASSERT_TRUE(compute_pipeline_2);
295 
296  auto cmd_buffer = context->CreateCommandBuffer();
297  auto pass = cmd_buffer->CreateComputePass();
298  ASSERT_TRUE(pass && pass->IsValid());
299 
300  static constexpr size_t kCount1 = 5;
301  static constexpr size_t kCount2 = kCount1 * 2;
302 
303  CS1::Input<kCount1> input_1;
304  input_1.count = kCount1;
305  for (size_t i = 0; i < kCount1; i++) {
306  input_1.elements[i] = i;
307  }
308 
309  CS2::Input<kCount2> input_2;
310  input_2.count = kCount2;
311  for (size_t i = 0; i < kCount2; i++) {
312  input_2.elements[i] = i;
313  }
314 
315  auto output_buffer_1 = CreateHostVisibleDeviceBuffer<CS1::Output<kCount2>>(
316  context, "Output Buffer Stage 1");
317  auto output_buffer_2 = CreateHostVisibleDeviceBuffer<CS2::Output<kCount2>>(
318  context, "Output Buffer Stage 2");
319 
320  {
321  pass->SetPipeline(compute_pipeline_1);
322 
323  CS1::BindInput(*pass, host_buffer->EmplaceStorageBuffer(input_1));
324  CS1::BindOutput(*pass, DeviceBuffer::AsBufferView(output_buffer_1));
325 
326  ASSERT_TRUE(pass->Compute(ISize(512, 1)).ok());
327  pass->AddBufferMemoryBarrier();
328  }
329 
330  {
331  pass->SetPipeline(compute_pipeline_2);
332 
333  CS1::BindInput(*pass, DeviceBuffer::AsBufferView(output_buffer_1));
334  CS2::BindOutput(*pass, DeviceBuffer::AsBufferView(output_buffer_2));
335  ASSERT_TRUE(pass->Compute(ISize(512, 1)).ok());
336  }
337 
338  ASSERT_TRUE(pass->EncodeCommands());
339 
340  fml::AutoResetWaitableEvent latch;
341  ASSERT_TRUE(
342  context->GetCommandQueue()
343  ->Submit({cmd_buffer},
344  [&latch, &output_buffer_1,
345  &output_buffer_2](CommandBuffer::Status status) {
346  EXPECT_EQ(status, CommandBuffer::Status::kCompleted);
347 
348  CS1::Output<kCount2>* output_1 =
349  reinterpret_cast<CS1::Output<kCount2>*>(
350  output_buffer_1->OnGetContents());
351  EXPECT_TRUE(output_1);
352  EXPECT_EQ(output_1->count, 10u);
353  EXPECT_THAT(
354  output_1->elements,
355  ::testing::ElementsAre(0, 0, 2, 3, 4, 6, 6, 9, 8, 12));
356 
357  CS2::Output<kCount2>* output_2 =
358  reinterpret_cast<CS2::Output<kCount2>*>(
359  output_buffer_2->OnGetContents());
360  EXPECT_TRUE(output_2);
361  EXPECT_EQ(output_2->count, 10u);
362  EXPECT_THAT(output_2->elements,
363  ::testing::ElementsAre(0, 0, 4, 6, 8, 12, 12,
364  18, 16, 24));
365 
366  latch.Signal();
367  })
368  .ok());
369 
370  latch.Wait();
371 }

References impeller::kCount1.

◆ TEST_P() [262/456]

impeller::testing::TEST_P ( ComputeTest  ,
ReturnsEarlyWhenAnyGridDimensionIsZero   
)

Definition at line 452 of file compute_unittests.cc.

452  {
453  using CS = SampleComputeShader;
454  auto context = GetContext();
455  auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
456  ASSERT_TRUE(context);
457  ASSERT_TRUE(context->GetCapabilities()->SupportsCompute());
458 
459  using SamplePipelineBuilder = ComputePipelineBuilder<CS>;
460  auto pipeline_desc =
461  SamplePipelineBuilder::MakeDefaultPipelineDescriptor(*context);
462  ASSERT_TRUE(pipeline_desc.has_value());
463  auto compute_pipeline =
464  context->GetPipelineLibrary()->GetPipeline(pipeline_desc).Get();
465  ASSERT_TRUE(compute_pipeline);
466 
467  auto cmd_buffer = context->CreateCommandBuffer();
468  auto pass = cmd_buffer->CreateComputePass();
469  ASSERT_TRUE(pass && pass->IsValid());
470 
471  static constexpr size_t kCount = 5;
472 
473  pass->SetPipeline(compute_pipeline);
474 
475  CS::Info info{.count = kCount};
476  CS::Input0<kCount> input_0;
477  CS::Input1<kCount> input_1;
478  for (size_t i = 0; i < kCount; i++) {
479  input_0.elements[i] = Vector4(2.0 + i, 3.0 + i, 4.0 + i, 5.0 * i);
480  input_1.elements[i] = Vector4(6.0, 7.0, 8.0, 9.0);
481  }
482 
483  input_0.fixed_array[1] = IPoint32(2, 2);
484  input_1.fixed_array[0] = UintPoint32(3, 3);
485  input_0.some_int = 5;
486  input_1.some_struct = CS::SomeStruct{.vf = Point(3, 4), .i = 42};
487 
488  auto output_buffer = CreateHostVisibleDeviceBuffer<CS::Output<kCount>>(
489  context, "Output Buffer");
490 
491  CS::BindInfo(*pass, host_buffer->EmplaceUniform(info));
492  CS::BindInput0(*pass, host_buffer->EmplaceStorageBuffer(input_0));
493  CS::BindInput1(*pass, host_buffer->EmplaceStorageBuffer(input_1));
494  CS::BindOutput(*pass, DeviceBuffer::AsBufferView(output_buffer));
495 
496  // Intentionally making the grid size zero in one dimension. No GPU will
497  // tolerate this.
498  EXPECT_FALSE(pass->Compute(ISize(0, 1)).ok());
499  pass->EncodeCommands();
500 }

◆ TEST_P() [263/456]

impeller::testing::TEST_P ( DisplayListTest  ,
CanBlendDstOverAndDstCorrectly   
)

Definition at line 1238 of file dl_unittests.cc.

1238  {
1239  flutter::DisplayListBuilder builder;
1240 
1241  {
1242  builder.SaveLayer(nullptr, nullptr);
1243  builder.Translate(100, 100);
1244  flutter::DlPaint paint;
1245  paint.setColor(flutter::DlColor::kRed());
1246  builder.DrawRect(SkRect::MakeSize({200, 200}), paint);
1247  paint.setColor(flutter::DlColor::kBlue().withAlpha(127));
1248  paint.setBlendMode(flutter::DlBlendMode::kSrcOver);
1249  builder.DrawRect(SkRect::MakeSize({200, 200}), paint);
1250  builder.Restore();
1251  }
1252  {
1253  builder.SaveLayer(nullptr, nullptr);
1254  builder.Translate(300, 100);
1255  flutter::DlPaint paint;
1256  paint.setColor(flutter::DlColor::kBlue().withAlpha(127));
1257  builder.DrawRect(SkRect::MakeSize({200, 200}), paint);
1258  paint.setColor(flutter::DlColor::kRed());
1259  paint.setBlendMode(flutter::DlBlendMode::kDstOver);
1260  builder.DrawRect(SkRect::MakeSize({200, 200}), paint);
1261  builder.Restore();
1262  }
1263  {
1264  builder.SaveLayer(nullptr, nullptr);
1265  builder.Translate(100, 300);
1266  flutter::DlPaint paint;
1267  paint.setColor(flutter::DlColor::kRed());
1268  builder.DrawRect(SkRect::MakeSize({200, 200}), paint);
1269  paint.setColor(flutter::DlColor::kBlue().withAlpha(127));
1270  paint.setBlendMode(flutter::DlBlendMode::kSrc);
1271  builder.DrawRect(SkRect::MakeSize({200, 200}), paint);
1272  builder.Restore();
1273  }
1274  {
1275  builder.SaveLayer(nullptr, nullptr);
1276  builder.Translate(300, 300);
1277  flutter::DlPaint paint;
1278  paint.setColor(flutter::DlColor::kBlue().withAlpha(127));
1279  builder.DrawRect(SkRect::MakeSize({200, 200}), paint);
1280  paint.setColor(flutter::DlColor::kRed());
1281  paint.setBlendMode(flutter::DlBlendMode::kDst);
1282  builder.DrawRect(SkRect::MakeSize({200, 200}), paint);
1283  builder.Restore();
1284  }
1285 
1286  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1287 }

References paint.

◆ TEST_P() [264/456]

impeller::testing::TEST_P ( DisplayListTest  ,
CanClampTheResultingColorOfColorMatrixFilter   
)

Definition at line 616 of file dl_unittests.cc.

616  {
617  auto texture = CreateTextureForFixture("boston.jpg");
618  const float inner_color_matrix[20] = {
619  1, 0, 0, 0, 0, //
620  0, 1, 0, 0, 0, //
621  0, 0, 1, 0, 0, //
622  0, 0, 0, 2, 0, //
623  };
624  const float outer_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, 0.5, 0, //
629  };
630  auto inner_color_filter =
631  std::make_shared<flutter::DlMatrixColorFilter>(inner_color_matrix);
632  auto outer_color_filter =
633  std::make_shared<flutter::DlMatrixColorFilter>(outer_color_matrix);
634  auto inner =
635  std::make_shared<flutter::DlColorFilterImageFilter>(inner_color_filter);
636  auto outer =
637  std::make_shared<flutter::DlColorFilterImageFilter>(outer_color_filter);
638  auto compose = std::make_shared<flutter::DlComposeImageFilter>(outer, inner);
639 
640  flutter::DisplayListBuilder builder;
641  flutter::DlPaint paint;
642  paint.setImageFilter(compose.get());
643  builder.DrawImage(DlImageImpeller::Make(texture), SkPoint::Make(100, 100),
644  flutter::DlImageSampling::kNearestNeighbor, &paint);
645  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
646 }

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

◆ TEST_P() [265/456]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawAnOpenPath   
)

Definition at line 406 of file dl_unittests.cc.

406  {
407  flutter::DisplayListBuilder builder;
408  flutter::DlPaint paint;
409 
410  paint.setColor(flutter::DlColor::kRed());
411  paint.setDrawStyle(flutter::DlDrawStyle::kStroke);
412  paint.setStrokeWidth(10);
413 
414  builder.Translate(300, 300);
415 
416  // Move to (50, 50) and draw lines from:
417  // 1. (50, height)
418  // 2. (width, height)
419  // 3. (width, 50)
420  SkPath path;
421  path.moveTo(50, 50);
422  path.lineTo(50, 100);
423  path.lineTo(100, 100);
424  path.lineTo(100, 50);
425  builder.DrawPath(path, paint);
426 
427  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
428 }

References paint.

◆ TEST_P() [266/456]

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 = SkRect::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 }

References impeller::DrawPlaygroundLine(), paint, scale, stroke_width, and impeller::Color::White().

◆ TEST_P() [267/456]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawBackdropFilter   
)

Definition at line 648 of file dl_unittests.cc.

648  {
649  auto texture = CreateTextureForFixture("embarcadero.jpg");
650 
651  auto callback = [&]() {
652  static float sigma[] = {10, 10};
653  static float ctm_scale = 1;
654  static bool use_bounds = true;
655  static bool draw_circle = true;
656  static bool add_clip = true;
657 
658  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
659  ImGui::SliderFloat2("Sigma", sigma, 0, 100);
660  ImGui::SliderFloat("Scale", &ctm_scale, 0, 10);
661  ImGui::NewLine();
662  ImGui::TextWrapped(
663  "If everything is working correctly, none of the options below should "
664  "impact the filter's appearance.");
665  ImGui::Checkbox("Use SaveLayer bounds", &use_bounds);
666  ImGui::Checkbox("Draw child element", &draw_circle);
667  ImGui::Checkbox("Add pre-clip", &add_clip);
668  ImGui::End();
669 
670  flutter::DisplayListBuilder builder;
671 
672  Vector2 scale = ctm_scale * GetContentScale();
673  builder.Scale(scale.x, scale.y);
674 
675  auto filter = flutter::DlBlurImageFilter(sigma[0], sigma[1],
676  flutter::DlTileMode::kClamp);
677 
678  std::optional<SkRect> bounds;
679  if (use_bounds) {
680  static PlaygroundPoint point_a(Point(350, 150), 20, Color::White());
681  static PlaygroundPoint point_b(Point(800, 600), 20, Color::White());
682  auto [p1, p2] = DrawPlaygroundLine(point_a, point_b);
683  bounds = SkRect::MakeLTRB(p1.x, p1.y, p2.x, p2.y);
684  }
685 
686  // Insert a clip to test that the backdrop filter handles stencil depths > 0
687  // correctly.
688  if (add_clip) {
689  builder.ClipRect(SkRect::MakeLTRB(0, 0, 99999, 99999),
690  flutter::DlCanvas::ClipOp::kIntersect, true);
691  }
692 
693  builder.DrawImage(DlImageImpeller::Make(texture), SkPoint::Make(200, 200),
694  flutter::DlImageSampling::kNearestNeighbor, nullptr);
695  builder.SaveLayer(bounds.has_value() ? &bounds.value() : nullptr, nullptr,
696  &filter);
697 
698  if (draw_circle) {
699  static PlaygroundPoint center_point(Point(500, 400), 20, Color::Red());
700  auto circle_center = DrawPlaygroundPoint(center_point);
701 
702  flutter::DlPaint paint;
703  paint.setDrawStyle(flutter::DlDrawStyle::kStroke);
704  paint.setStrokeCap(flutter::DlStrokeCap::kButt);
705  paint.setStrokeJoin(flutter::DlStrokeJoin::kBevel);
706  paint.setStrokeWidth(10);
707  paint.setColor(flutter::DlColor::kRed().withAlpha(100));
708  builder.DrawCircle({circle_center.x, circle_center.y}, 100, paint);
709  }
710 
711  return builder.Build();
712  };
713 
714  ASSERT_TRUE(OpenPlaygroundHere(callback));
715 }

References impeller::DrawPlaygroundLine(), impeller::DrawPlaygroundPoint(), impeller::DlImageImpeller::Make(), paint, impeller::Color::Red(), scale, and impeller::Color::White().

◆ TEST_P() [268/456]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawCapsAndJoins   
)

Definition at line 106 of file dl_unittests.cc.

106  {
107  flutter::DisplayListBuilder builder;
108  flutter::DlPaint paint;
109 
110  paint.setDrawStyle(flutter::DlDrawStyle::kStroke);
111  paint.setStrokeWidth(30);
112  paint.setColor(flutter::DlColor::kRed());
113 
114  auto path =
115  SkPathBuilder{}.moveTo(-50, 0).lineTo(0, -50).lineTo(50, 0).snapshot();
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 }

References paint.

◆ TEST_P() [269/456]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawCorrectlyWithColorFilterAndImageFilter   
)

Definition at line 1289 of file dl_unittests.cc.

1289  {
1290  flutter::DisplayListBuilder builder;
1291  const float green_color_matrix[20] = {
1292  0, 0, 0, 0, 0, //
1293  0, 0, 0, 0, 1, //
1294  0, 0, 0, 0, 0, //
1295  0, 0, 0, 1, 0, //
1296  };
1297  const float blue_color_matrix[20] = {
1298  0, 0, 0, 0, 0, //
1299  0, 0, 0, 0, 0, //
1300  0, 0, 0, 0, 1, //
1301  0, 0, 0, 1, 0, //
1302  };
1303  auto green_color_filter =
1304  std::make_shared<flutter::DlMatrixColorFilter>(green_color_matrix);
1305  auto blue_color_filter =
1306  std::make_shared<flutter::DlMatrixColorFilter>(blue_color_matrix);
1307  auto blue_image_filter =
1308  std::make_shared<flutter::DlColorFilterImageFilter>(blue_color_filter);
1309 
1310  flutter::DlPaint paint;
1311  paint.setColor(flutter::DlColor::kRed());
1312  paint.setColorFilter(green_color_filter);
1313  paint.setImageFilter(blue_image_filter);
1314  builder.DrawRect(SkRect::MakeLTRB(100, 100, 500, 500), paint);
1315  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1316 }

References paint.

◆ TEST_P() [270/456]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawImage   
)

Definition at line 98 of file dl_unittests.cc.

98  {
99  auto texture = CreateTextureForFixture("embarcadero.jpg");
100  flutter::DisplayListBuilder builder;
101  builder.DrawImage(DlImageImpeller::Make(texture), SkPoint::Make(100, 100),
102  flutter::DlImageSampling::kNearestNeighbor, nullptr);
103  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
104 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [271/456]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawNinePatchImage   
)

Definition at line 717 of file dl_unittests.cc.

717  {
718  // Image is drawn with corners to scale and center pieces stretched to fit.
719  auto texture = CreateTextureForFixture("embarcadero.jpg");
720  flutter::DisplayListBuilder builder;
721  auto size = texture->GetSize();
722  builder.DrawImageNine(
723  DlImageImpeller::Make(texture),
724  SkIRect::MakeLTRB(size.width / 4, size.height / 4, size.width * 3 / 4,
725  size.height * 3 / 4),
726  SkRect::MakeLTRB(0, 0, size.width * 2, size.height * 2),
727  flutter::DlFilterMode::kNearest, nullptr);
728  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
729 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [272/456]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawNinePatchImageCenterBiggerThanDest   
)

Definition at line 763 of file dl_unittests.cc.

763  {
764  // Edge case, the width and height of the corners does not leave any
765  // room for the center slices. Only the corners are displayed.
766  auto texture = CreateTextureForFixture("embarcadero.jpg");
767  flutter::DisplayListBuilder builder;
768  auto size = texture->GetSize();
769  builder.DrawImageNine(
770  DlImageImpeller::Make(texture),
771  SkIRect::MakeLTRB(size.width / 4, size.height / 4, size.width * 3 / 4,
772  size.height * 3 / 4),
773  SkRect::MakeLTRB(0, 0, size.width / 2, size.height / 2),
774  flutter::DlFilterMode::kNearest, nullptr);
775  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
776 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [273/456]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawNinePatchImageCenterHeightBiggerThanDest   
)

Definition at line 747 of file dl_unittests.cc.

747  {
748  // Edge case, the height of the corners does not leave any room for the
749  // center slice. The center (across the horizontal axis) is folded out of the
750  // resulting image.
751  auto texture = CreateTextureForFixture("embarcadero.jpg");
752  flutter::DisplayListBuilder builder;
753  auto size = texture->GetSize();
754  builder.DrawImageNine(
755  DlImageImpeller::Make(texture),
756  SkIRect::MakeLTRB(size.width / 4, size.height / 4, size.width * 3 / 4,
757  size.height * 3 / 4),
758  SkRect::MakeLTRB(0, 0, size.width, size.height / 2),
759  flutter::DlFilterMode::kNearest, nullptr);
760  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
761 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [274/456]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawNinePatchImageCenterWidthBiggerThanDest   
)

Definition at line 731 of file dl_unittests.cc.

731  {
732  // Edge case, the width of the corners does not leave any room for the
733  // center slice. The center (across the vertical axis) is folded out of the
734  // resulting image.
735  auto texture = CreateTextureForFixture("embarcadero.jpg");
736  flutter::DisplayListBuilder builder;
737  auto size = texture->GetSize();
738  builder.DrawImageNine(
739  DlImageImpeller::Make(texture),
740  SkIRect::MakeLTRB(size.width / 4, size.height / 4, size.width * 3 / 4,
741  size.height * 3 / 4),
742  SkRect::MakeLTRB(0, 0, size.width / 2, size.height),
743  flutter::DlFilterMode::kNearest, nullptr);
744  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
745 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [275/456]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawNinePatchImageCornersScaledDown   
)

Definition at line 778 of file dl_unittests.cc.

778  {
779  // Edge case, there is not enough room for the corners to be drawn
780  // without scaling them down.
781  auto texture = CreateTextureForFixture("embarcadero.jpg");
782  flutter::DisplayListBuilder builder;
783  auto size = texture->GetSize();
784  builder.DrawImageNine(
785  DlImageImpeller::Make(texture),
786  SkIRect::MakeLTRB(size.width / 4, size.height / 4, size.width * 3 / 4,
787  size.height * 3 / 4),
788  SkRect::MakeLTRB(0, 0, size.width / 4, size.height / 4),
789  flutter::DlFilterMode::kNearest, nullptr);
790  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
791 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [276/456]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawPaintWithColorSource   
)

Definition at line 1186 of file dl_unittests.cc.

1186  {
1187  const flutter::DlColor colors[2] = {
1188  flutter::DlColor(0xFFF44336),
1189  flutter::DlColor(0xFF2196F3),
1190  };
1191  const float stops[2] = {0.0, 1.0};
1192  flutter::DlPaint paint;
1193  flutter::DisplayListBuilder builder;
1194  auto clip_bounds = SkRect::MakeWH(300.0, 300.0);
1195  builder.Save();
1196  builder.Translate(100, 100);
1197  builder.ClipRect(clip_bounds, flutter::DlCanvas::ClipOp::kIntersect, false);
1198  auto linear =
1199  flutter::DlColorSource::MakeLinear({0.0, 0.0}, {100.0, 100.0}, 2, colors,
1200  stops, flutter::DlTileMode::kRepeat);
1201  paint.setColorSource(linear);
1202  builder.DrawPaint(paint);
1203  builder.Restore();
1204 
1205  builder.Save();
1206  builder.Translate(500, 100);
1207  builder.ClipRect(clip_bounds, flutter::DlCanvas::ClipOp::kIntersect, false);
1208  auto radial = flutter::DlColorSource::MakeRadial(
1209  {100.0, 100.0}, 100.0, 2, colors, stops, flutter::DlTileMode::kRepeat);
1210  paint.setColorSource(radial);
1211  builder.DrawPaint(paint);
1212  builder.Restore();
1213 
1214  builder.Save();
1215  builder.Translate(100, 500);
1216  builder.ClipRect(clip_bounds, flutter::DlCanvas::ClipOp::kIntersect, false);
1217  auto sweep =
1218  flutter::DlColorSource::MakeSweep({100.0, 100.0}, 180.0, 270.0, 2, colors,
1219  stops, flutter::DlTileMode::kRepeat);
1220  paint.setColorSource(sweep);
1221  builder.DrawPaint(paint);
1222  builder.Restore();
1223 
1224  builder.Save();
1225  builder.Translate(500, 500);
1226  builder.ClipRect(clip_bounds, flutter::DlCanvas::ClipOp::kIntersect, false);
1227  auto texture = CreateTextureForFixture("table_mountain_nx.png");
1228  auto image = std::make_shared<flutter::DlImageColorSource>(
1229  DlImageImpeller::Make(texture), flutter::DlTileMode::kRepeat,
1230  flutter::DlTileMode::kRepeat);
1231  paint.setColorSource(image);
1232  builder.DrawPaint(paint);
1233  builder.Restore();
1234 
1235  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1236 }

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

◆ TEST_P() [277/456]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawPoints   
)

Definition at line 805 of file dl_unittests.cc.

805  {
806  flutter::DisplayListBuilder builder;
807  SkPoint points[7] = {
808  {0, 0}, //
809  {100, 100}, //
810  {100, 0}, //
811  {0, 100}, //
812  {0, 0}, //
813  {48, 48}, //
814  {52, 52}, //
815  };
816  std::vector<flutter::DlStrokeCap> caps = {
817  flutter::DlStrokeCap::kButt,
818  flutter::DlStrokeCap::kRound,
819  flutter::DlStrokeCap::kSquare,
820  };
821  flutter::DlPaint paint =
822  flutter::DlPaint() //
823  .setColor(flutter::DlColor::kYellow().withAlpha(127)) //
824  .setStrokeWidth(20);
825  builder.Translate(50, 50);
826  for (auto cap : caps) {
827  paint.setStrokeCap(cap);
828  builder.Save();
829  builder.DrawPoints(flutter::DlCanvas::PointMode::kPoints, 7, points, paint);
830  builder.Translate(150, 0);
831  builder.DrawPoints(flutter::DlCanvas::PointMode::kLines, 5, points, paint);
832  builder.Translate(150, 0);
833  builder.DrawPoints(flutter::DlCanvas::PointMode::kPolygon, 5, points,
834  paint);
835  builder.Restore();
836  builder.Translate(0, 150);
837  }
838  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
839 }

References paint.

◆ TEST_P() [278/456]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawRect   
)

Definition at line 49 of file dl_unittests.cc.

49  {
50  flutter::DisplayListBuilder builder;
51  builder.DrawRect(SkRect::MakeXYWH(10, 10, 100, 100),
52  flutter::DlPaint(flutter::DlColor::kBlue()));
53  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
54 }

◆ TEST_P() [279/456]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawRectWithLinearToSrgbColorFilter   
)

Definition at line 1170 of file dl_unittests.cc.

1170  {
1171  flutter::DlPaint paint;
1172  paint.setColor(flutter::DlColor(0xFF2196F3).withAlpha(128));
1173  flutter::DisplayListBuilder builder;
1174  paint.setColorFilter(
1175  flutter::DlLinearToSrgbGammaColorFilter::kInstance.get());
1176  builder.DrawRect(SkRect::MakeXYWH(0, 0, 200, 200), paint);
1177  builder.Translate(0, 200);
1178 
1179  paint.setColorFilter(
1180  flutter::DlSrgbToLinearGammaColorFilter::kInstance.get());
1181  builder.DrawRect(SkRect::MakeXYWH(0, 0, 200, 200), paint);
1182 
1183  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1184 }

References paint.

◆ TEST_P() [280/456]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawShadow   
)

Definition at line 864 of file dl_unittests.cc.

864  {
865  flutter::DisplayListBuilder builder;
866  flutter::DlPaint paint;
867 
868  auto content_scale = GetContentScale() * 0.8;
869  builder.Scale(content_scale.x, content_scale.y);
870 
871  constexpr size_t star_spikes = 5;
872  constexpr SkScalar half_spike_rotation = kPi / star_spikes;
873  constexpr SkScalar radius = 40;
874  constexpr SkScalar spike_size = 10;
875  constexpr SkScalar outer_radius = radius + spike_size;
876  constexpr SkScalar inner_radius = radius - spike_size;
877  std::array<SkPoint, star_spikes * 2> star;
878  for (size_t i = 0; i < star_spikes; i++) {
879  const SkScalar rotation = half_spike_rotation * i * 2;
880  star[i * 2] = SkPoint::Make(50 + std::sin(rotation) * outer_radius,
881  50 - std::cos(rotation) * outer_radius);
882  star[i * 2 + 1] = SkPoint::Make(
883  50 + std::sin(rotation + half_spike_rotation) * inner_radius,
884  50 - std::cos(rotation + half_spike_rotation) * inner_radius);
885  }
886 
887  std::array<SkPath, 4> paths = {
888  SkPath{}.addRect(SkRect::MakeXYWH(0, 0, 200, 100)),
889  SkPath{}.addRRect(
890  SkRRect::MakeRectXY(SkRect::MakeXYWH(20, 0, 200, 100), 30, 30)),
891  SkPath{}.addCircle(100, 50, 50),
892  SkPath{}.addPoly(star.data(), star.size(), true),
893  };
894  paint.setColor(flutter::DlColor::kWhite());
895  builder.DrawPaint(paint);
896  paint.setColor(flutter::DlColor::kCyan());
897  builder.Translate(100, 50);
898  for (size_t x = 0; x < paths.size(); x++) {
899  builder.Save();
900  for (size_t y = 0; y < 6; y++) {
901  builder.DrawShadow(paths[x], flutter::DlColor::kBlack(), 3 + y * 8, false,
902  1);
903  builder.DrawPath(paths[x], paint);
904  builder.Translate(0, 150);
905  }
906  builder.Restore();
907  builder.Translate(250, 0);
908  }
909 
910  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
911 }

References impeller::kPi, and paint.

◆ TEST_P() [281/456]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawStrokedText   
)

Definition at line 466 of file dl_unittests.cc.

466  {
467  flutter::DisplayListBuilder builder;
468  flutter::DlPaint paint;
469 
470  paint.setDrawStyle(flutter::DlDrawStyle::kStroke);
471  paint.setColor(flutter::DlColor::kRed());
472  builder.DrawTextBlob(
473  SkTextBlob::MakeFromString("stoked about stroked text", CreateTestFont()),
474  250, 250, paint);
475 
476  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
477 }

References paint.

◆ TEST_P() [282/456]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawTextBlob   
)

Definition at line 56 of file dl_unittests.cc.

56  {
57  flutter::DisplayListBuilder builder;
58  builder.DrawTextBlob(SkTextBlob::MakeFromString("Hello", CreateTestFont()),
59  100, 100, flutter::DlPaint(flutter::DlColor::kBlue()));
60  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
61 }

◆ TEST_P() [283/456]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawTextBlobWithGradient   
)

Definition at line 63 of file dl_unittests.cc.

63  {
64  flutter::DisplayListBuilder builder;
65 
66  std::vector<flutter::DlColor> colors = {flutter::DlColor::kBlue(),
67  flutter::DlColor::kRed()};
68  const float stops[2] = {0.0, 1.0};
69 
70  auto linear = flutter::DlColorSource::MakeLinear({0.0, 0.0}, {300.0, 300.0},
71  2, colors.data(), stops,
72  flutter::DlTileMode::kClamp);
73  flutter::DlPaint paint;
74  paint.setColorSource(linear);
75 
76  builder.DrawTextBlob(
77  SkTextBlob::MakeFromString("Hello World", CreateTestFont()), 100, 100,
78  paint);
79  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
80 }

References paint.

◆ TEST_P() [284/456]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawTextWithSaveLayer   
)

Definition at line 82 of file dl_unittests.cc.

82  {
83  flutter::DisplayListBuilder builder;
84  builder.DrawTextBlob(SkTextBlob::MakeFromString("Hello", CreateTestFont()),
85  100, 100, flutter::DlPaint(flutter::DlColor::kRed()));
86 
87  flutter::DlPaint save_paint;
88  float alpha = 0.5;
89  save_paint.setAlpha(static_cast<uint8_t>(255 * alpha));
90  builder.SaveLayer(nullptr, &save_paint);
91  builder.DrawTextBlob(SkTextBlob::MakeFromString("Hello with half alpha",
92  CreateTestFontOfSize(100)),
93  100, 300, flutter::DlPaint(flutter::DlColor::kRed()));
94  builder.Restore();
95  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
96 }

◆ TEST_P() [285/456]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawWithBlendColorFilter   
)

Definition at line 518 of file dl_unittests.cc.

518  {
519  auto texture = CreateTextureForFixture("embarcadero.jpg");
520  flutter::DisplayListBuilder builder;
521  flutter::DlPaint paint;
522 
523  // Pipeline blended image.
524  {
525  auto filter = flutter::DlBlendColorFilter(flutter::DlColor::kYellow(),
526  flutter::DlBlendMode::kModulate);
527  paint.setColorFilter(&filter);
528  builder.DrawImage(DlImageImpeller::Make(texture), SkPoint::Make(100, 100),
529  flutter::DlImageSampling::kNearestNeighbor, &paint);
530  }
531 
532  // Advanced blended image.
533  {
534  auto filter = flutter::DlBlendColorFilter(flutter::DlColor::kRed(),
535  flutter::DlBlendMode::kScreen);
536  paint.setColorFilter(&filter);
537  builder.DrawImage(DlImageImpeller::Make(texture), SkPoint::Make(250, 250),
538  flutter::DlImageSampling::kNearestNeighbor, &paint);
539  }
540 
541  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
542 }

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

◆ TEST_P() [286/456]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawWithColorFilterImageFilter   
)

Definition at line 544 of file dl_unittests.cc.

544  {
545  const float invert_color_matrix[20] = {
546  -1, 0, 0, 0, 1, //
547  0, -1, 0, 0, 1, //
548  0, 0, -1, 0, 1, //
549  0, 0, 0, 1, 0, //
550  };
551  auto texture = CreateTextureForFixture("boston.jpg");
552  flutter::DisplayListBuilder builder;
553  flutter::DlPaint paint;
554 
555  auto color_filter =
556  std::make_shared<flutter::DlMatrixColorFilter>(invert_color_matrix);
557  auto image_filter =
558  std::make_shared<flutter::DlColorFilterImageFilter>(color_filter);
559 
560  paint.setImageFilter(image_filter.get());
561  builder.DrawImage(DlImageImpeller::Make(texture), SkPoint::Make(100, 100),
562  flutter::DlImageSampling::kNearestNeighbor, &paint);
563 
564  builder.Translate(0, 700);
565  paint.setColorFilter(color_filter.get());
566  builder.DrawImage(DlImageImpeller::Make(texture), SkPoint::Make(100, 100),
567  flutter::DlImageSampling::kNearestNeighbor, &paint);
568  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
569 }

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

◆ TEST_P() [287/456]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawWithComposeImageFilter   
)

Definition at line 596 of file dl_unittests.cc.

596  {
597  auto texture = CreateTextureForFixture("boston.jpg");
598  flutter::DisplayListBuilder builder;
599  flutter::DlPaint paint;
600 
601  auto dilate = std::make_shared<flutter::DlDilateImageFilter>(10.0, 10.0);
602  auto erode = std::make_shared<flutter::DlErodeImageFilter>(10.0, 10.0);
603  auto open = std::make_shared<flutter::DlComposeImageFilter>(dilate, erode);
604  auto close = std::make_shared<flutter::DlComposeImageFilter>(erode, dilate);
605 
606  paint.setImageFilter(open.get());
607  builder.DrawImage(DlImageImpeller::Make(texture), SkPoint::Make(100, 100),
608  flutter::DlImageSampling::kNearestNeighbor, &paint);
609  builder.Translate(0, 700);
610  paint.setImageFilter(close.get());
611  builder.DrawImage(DlImageImpeller::Make(texture), SkPoint::Make(100, 100),
612  flutter::DlImageSampling::kNearestNeighbor, &paint);
613  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
614 }

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

◆ TEST_P() [288/456]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawWithImageBlurFilter   
)

Definition at line 571 of file dl_unittests.cc.

571  {
572  auto texture = CreateTextureForFixture("embarcadero.jpg");
573 
574  auto callback = [&]() {
575  static float sigma[] = {10, 10};
576 
577  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
578  ImGui::SliderFloat2("Sigma", sigma, 0, 100);
579  ImGui::End();
580 
581  flutter::DisplayListBuilder builder;
582  flutter::DlPaint paint;
583 
584  auto filter = flutter::DlBlurImageFilter(sigma[0], sigma[1],
585  flutter::DlTileMode::kClamp);
586  paint.setImageFilter(&filter);
587  builder.DrawImage(DlImageImpeller::Make(texture), SkPoint::Make(200, 200),
588  flutter::DlImageSampling::kNearestNeighbor, &paint);
589 
590  return builder.Build();
591  };
592 
593  ASSERT_TRUE(OpenPlaygroundHere(callback));
594 }

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

◆ TEST_P() [289/456]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawWithMaskBlur   
)

Definition at line 430 of file dl_unittests.cc.

430  {
431  auto texture = CreateTextureForFixture("embarcadero.jpg");
432  flutter::DisplayListBuilder builder;
433  flutter::DlPaint paint;
434 
435  // Mask blurred image.
436  {
437  auto filter =
438  flutter::DlBlurMaskFilter(flutter::DlBlurStyle::kNormal, 10.0f);
439  paint.setMaskFilter(&filter);
440  builder.DrawImage(DlImageImpeller::Make(texture), SkPoint::Make(100, 100),
441  flutter::DlImageSampling::kNearestNeighbor, &paint);
442  }
443 
444  // Mask blurred filled path.
445  {
446  paint.setColor(flutter::DlColor::kYellow());
447  auto filter =
448  flutter::DlBlurMaskFilter(flutter::DlBlurStyle::kOuter, 10.0f);
449  paint.setMaskFilter(&filter);
450  builder.DrawArc(SkRect::MakeXYWH(410, 110, 100, 100), 45, 270, true, paint);
451  }
452 
453  // Mask blurred text.
454  {
455  auto filter =
456  flutter::DlBlurMaskFilter(flutter::DlBlurStyle::kSolid, 10.0f);
457  paint.setMaskFilter(&filter);
458  builder.DrawTextBlob(
459  SkTextBlob::MakeFromString("Testing", CreateTestFont()), 220, 170,
460  paint);
461  }
462 
463  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
464 }

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

◆ TEST_P() [290/456]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawWithMatrixFilter   
)

Definition at line 1010 of file dl_unittests.cc.

1010  {
1011  auto boston = CreateTextureForFixture("boston.jpg");
1012 
1013  auto callback = [&]() {
1014  static int selected_matrix_type = 0;
1015  const char* matrix_type_names[] = {"Matrix", "Local Matrix"};
1016 
1017  static float ctm_translation[2] = {200, 200};
1018  static float ctm_scale[2] = {0.65, 0.65};
1019  static float ctm_skew[2] = {0, 0};
1020 
1021  static bool enable = true;
1022  static float translation[2] = {100, 100};
1023  static float scale[2] = {0.8, 0.8};
1024  static float skew[2] = {0.2, 0.2};
1025 
1026  static bool enable_savelayer = true;
1027 
1028  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
1029  {
1030  ImGui::Combo("Filter type", &selected_matrix_type, matrix_type_names,
1031  sizeof(matrix_type_names) / sizeof(char*));
1032 
1033  ImGui::TextWrapped("Current Transform");
1034  ImGui::SliderFloat2("CTM Translation", ctm_translation, 0, 1000);
1035  ImGui::SliderFloat2("CTM Scale", ctm_scale, 0, 3);
1036  ImGui::SliderFloat2("CTM Skew", ctm_skew, -3, 3);
1037 
1038  ImGui::TextWrapped(
1039  "MatrixFilter and LocalMatrixFilter modify the CTM in the same way. "
1040  "The only difference is that MatrixFilter doesn't affect the effect "
1041  "transform, whereas LocalMatrixFilter does.");
1042  // Note: See this behavior in:
1043  // https://fiddle.skia.org/c/6cbb551ab36d06f163db8693972be954
1044  ImGui::Checkbox("Enable", &enable);
1045  ImGui::SliderFloat2("Filter Translation", translation, 0, 1000);
1046  ImGui::SliderFloat2("Filter Scale", scale, 0, 3);
1047  ImGui::SliderFloat2("Filter Skew", skew, -3, 3);
1048 
1049  ImGui::TextWrapped(
1050  "Rendering the filtered image within a layer can expose bounds "
1051  "issues. If the rendered image gets cut off when this setting is "
1052  "enabled, there's a coverage bug in the filter.");
1053  ImGui::Checkbox("Render in layer", &enable_savelayer);
1054  }
1055  ImGui::End();
1056 
1057  flutter::DisplayListBuilder builder;
1058  flutter::DlPaint paint;
1059 
1060  if (enable_savelayer) {
1061  builder.SaveLayer(nullptr, nullptr);
1062  }
1063  {
1064  auto content_scale = GetContentScale();
1065  builder.Scale(content_scale.x, content_scale.y);
1066 
1067  // Set the current transform
1068  auto ctm_matrix =
1069  SkMatrix::MakeAll(ctm_scale[0], ctm_skew[0], ctm_translation[0], //
1070  ctm_skew[1], ctm_scale[1], ctm_translation[1], //
1071  0, 0, 1);
1072  builder.Transform(ctm_matrix);
1073 
1074  // Set the matrix filter
1075  auto filter_matrix =
1076  SkMatrix::MakeAll(scale[0], skew[0], translation[0], //
1077  skew[1], scale[1], translation[1], //
1078  0, 0, 1);
1079 
1080  if (enable) {
1081  switch (selected_matrix_type) {
1082  case 0: {
1083  auto filter = flutter::DlMatrixImageFilter(
1084  filter_matrix, flutter::DlImageSampling::kLinear);
1085  paint.setImageFilter(&filter);
1086  break;
1087  }
1088  case 1: {
1089  auto internal_filter =
1090  flutter::DlBlurImageFilter(10, 10, flutter::DlTileMode::kDecal)
1091  .shared();
1092  auto filter = flutter::DlLocalMatrixImageFilter(filter_matrix,
1093  internal_filter);
1094  paint.setImageFilter(&filter);
1095  break;
1096  }
1097  }
1098  }
1099 
1100  builder.DrawImage(DlImageImpeller::Make(boston), {},
1101  flutter::DlImageSampling::kLinear, &paint);
1102  }
1103  if (enable_savelayer) {
1104  builder.Restore();
1105  }
1106 
1107  return builder.Build();
1108  };
1109 
1110  ASSERT_TRUE(OpenPlaygroundHere(callback));
1111 }

References impeller::DlImageImpeller::Make(), paint, and scale.

◆ TEST_P() [291/456]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawWithMatrixFilterWhenSavingLayer   
)

Definition at line 1113 of file dl_unittests.cc.

1113  {
1114  auto callback = [&]() {
1115  static float translation[2] = {0, 0};
1116  static bool enable_save_layer = true;
1117 
1118  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
1119  ImGui::SliderFloat2("Translation", translation, -130, 130);
1120  ImGui::Checkbox("Enable save layer", &enable_save_layer);
1121  ImGui::End();
1122 
1123  flutter::DisplayListBuilder builder;
1124  builder.Save();
1125  builder.Scale(2.0, 2.0);
1126  flutter::DlPaint paint;
1127  paint.setColor(flutter::DlColor::kYellow());
1128  builder.DrawRect(SkRect::MakeWH(300, 300), paint);
1129  paint.setStrokeWidth(1.0);
1130  paint.setDrawStyle(flutter::DlDrawStyle::kStroke);
1131  paint.setColor(flutter::DlColor::kBlack().withAlpha(0x80));
1132  builder.DrawLine(SkPoint::Make(150, 0), SkPoint::Make(150, 300), paint);
1133  builder.DrawLine(SkPoint::Make(0, 150), SkPoint::Make(300, 150), paint);
1134 
1135  flutter::DlPaint save_paint;
1136  SkRect bounds = SkRect::MakeXYWH(100, 100, 100, 100);
1137  SkMatrix translate_matrix =
1138  SkMatrix::Translate(translation[0], translation[1]);
1139  if (enable_save_layer) {
1140  auto filter = flutter::DlMatrixImageFilter(
1141  translate_matrix, flutter::DlImageSampling::kNearestNeighbor);
1142  save_paint.setImageFilter(filter.shared());
1143  builder.SaveLayer(&bounds, &save_paint);
1144  } else {
1145  builder.Save();
1146  builder.Transform(translate_matrix);
1147  }
1148 
1149  SkMatrix filter_matrix = SkMatrix::I();
1150  filter_matrix.postTranslate(-150, -150);
1151  filter_matrix.postScale(0.2f, 0.2f);
1152  filter_matrix.postTranslate(150, 150);
1153  auto filter = flutter::DlMatrixImageFilter(
1154  filter_matrix, flutter::DlImageSampling::kNearestNeighbor);
1155 
1156  save_paint.setImageFilter(filter.shared());
1157 
1158  builder.SaveLayer(&bounds, &save_paint);
1159  flutter::DlPaint paint2;
1160  paint2.setColor(flutter::DlColor::kBlue());
1161  builder.DrawRect(bounds, paint2);
1162  builder.Restore();
1163  builder.Restore();
1164  return builder.Build();
1165  };
1166 
1167  ASSERT_TRUE(OpenPlaygroundHere(callback));
1168 }

References paint.

◆ TEST_P() [292/456]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawWithOddPathWinding   
)

Definition at line 386 of file dl_unittests.cc.

386  {
387  flutter::DisplayListBuilder builder;
388  flutter::DlPaint paint;
389 
390  paint.setColor(flutter::DlColor::kRed());
391  paint.setDrawStyle(flutter::DlDrawStyle::kFill);
392 
393  builder.Translate(300, 300);
394  SkPath path;
395  path.setFillType(SkPathFillType::kEvenOdd);
396  path.addCircle(0, 0, 100);
397  path.addCircle(0, 0, 50);
398  builder.DrawPath(path, paint);
399 
400  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
401 }

References paint.

◆ TEST_P() [293/456]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawZeroLengthLine   
)

Definition at line 841 of file dl_unittests.cc.

841  {
842  flutter::DisplayListBuilder builder;
843  std::vector<flutter::DlStrokeCap> caps = {
844  flutter::DlStrokeCap::kButt,
845  flutter::DlStrokeCap::kRound,
846  flutter::DlStrokeCap::kSquare,
847  };
848  flutter::DlPaint paint =
849  flutter::DlPaint() //
850  .setColor(flutter::DlColor::kYellow().withAlpha(127)) //
851  .setDrawStyle(flutter::DlDrawStyle::kStroke) //
852  .setStrokeCap(flutter::DlStrokeCap::kButt) //
853  .setStrokeWidth(20);
854  SkPath path = SkPath().addPoly({{150, 50}, {150, 50}}, false);
855  for (auto cap : caps) {
856  paint.setStrokeCap(cap);
857  builder.DrawLine({50, 50}, {50, 50}, paint);
858  builder.DrawPath(path, paint);
859  builder.Translate(0, 150);
860  }
861  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
862 }

References paint.

◆ TEST_P() [294/456]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawZeroWidthLine   
)

Definition at line 976 of file dl_unittests.cc.

976  {
977  flutter::DisplayListBuilder builder;
978  std::vector<flutter::DlStrokeCap> caps = {
979  flutter::DlStrokeCap::kButt,
980  flutter::DlStrokeCap::kRound,
981  flutter::DlStrokeCap::kSquare,
982  };
983  flutter::DlPaint paint = //
984  flutter::DlPaint() //
985  .setColor(flutter::DlColor::kWhite()) //
986  .setDrawStyle(flutter::DlDrawStyle::kStroke) //
987  .setStrokeWidth(0);
988  flutter::DlPaint outline_paint = //
989  flutter::DlPaint() //
990  .setColor(flutter::DlColor::kYellow()) //
991  .setDrawStyle(flutter::DlDrawStyle::kStroke) //
992  .setStrokeCap(flutter::DlStrokeCap::kSquare) //
993  .setStrokeWidth(1);
994  SkPath path = SkPath().addPoly({{150, 50}, {160, 50}}, false);
995  for (auto cap : caps) {
996  paint.setStrokeCap(cap);
997  builder.DrawLine({50, 50}, {60, 50}, paint);
998  builder.DrawRect({45, 45, 65, 55}, outline_paint);
999  builder.DrawLine({100, 50}, {100, 50}, paint);
1000  if (cap != flutter::DlStrokeCap::kButt) {
1001  builder.DrawRect({95, 45, 105, 55}, outline_paint);
1002  }
1003  builder.DrawPath(path, paint);
1004  builder.DrawRect(path.getBounds().makeOutset(5, 5), outline_paint);
1005  builder.Translate(0, 150);
1006  }
1007  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1008 }

References paint.

◆ TEST_P() [295/456]

impeller::testing::TEST_P ( DisplayListTest  ,
ClipDrawRRectWithNonCircularRadii   
)

Definition at line 1393 of file dl_unittests.cc.

1393  {
1394  flutter::DisplayListBuilder builder;
1395 
1396  flutter::DlPaint fill_paint = //
1397  flutter::DlPaint() //
1398  .setColor(flutter::DlColor::kBlue()) //
1399  .setDrawStyle(flutter::DlDrawStyle::kFill) //
1400  .setStrokeWidth(10);
1401  flutter::DlPaint stroke_paint = //
1402  flutter::DlPaint() //
1403  .setColor(flutter::DlColor::kGreen()) //
1404  .setDrawStyle(flutter::DlDrawStyle::kStroke) //
1405  .setStrokeWidth(10);
1406 
1407  builder.DrawRRect(
1408  SkRRect::MakeRectXY(SkRect::MakeXYWH(500, 100, 300, 300), 120, 40),
1409  fill_paint);
1410  builder.DrawRRect(
1411  SkRRect::MakeRectXY(SkRect::MakeXYWH(500, 100, 300, 300), 120, 40),
1412  stroke_paint);
1413 
1414  builder.DrawRRect(
1415  SkRRect::MakeRectXY(SkRect::MakeXYWH(100, 500, 300, 300), 40, 120),
1416  fill_paint);
1417  builder.DrawRRect(
1418  SkRRect::MakeRectXY(SkRect::MakeXYWH(100, 500, 300, 300), 40, 120),
1419  stroke_paint);
1420 
1421  flutter::DlPaint reference_paint = //
1422  flutter::DlPaint() //
1423  .setColor(flutter::DlColor::kMidGrey()) //
1424  .setDrawStyle(flutter::DlDrawStyle::kFill) //
1425  .setStrokeWidth(10);
1426 
1427  builder.DrawRRect(
1428  SkRRect::MakeRectXY(SkRect::MakeXYWH(500, 500, 300, 300), 40, 40),
1429  reference_paint);
1430  builder.DrawRRect(
1431  SkRRect::MakeRectXY(SkRect::MakeXYWH(100, 100, 300, 300), 120, 120),
1432  reference_paint);
1433 
1434  flutter::DlPaint clip_fill_paint = //
1435  flutter::DlPaint() //
1436  .setColor(flutter::DlColor::kCyan()) //
1437  .setDrawStyle(flutter::DlDrawStyle::kFill) //
1438  .setStrokeWidth(10);
1439 
1440  builder.Save();
1441  builder.ClipRRect(
1442  SkRRect::MakeRectXY(SkRect::MakeXYWH(900, 100, 300, 300), 120, 40));
1443  builder.DrawPaint(clip_fill_paint);
1444  builder.Restore();
1445 
1446  builder.Save();
1447  builder.ClipRRect(
1448  SkRRect::MakeRectXY(SkRect::MakeXYWH(100, 900, 300, 300), 40, 120));
1449  builder.DrawPaint(clip_fill_paint);
1450  builder.Restore();
1451 
1452  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1453 }

◆ TEST_P() [296/456]

impeller::testing::TEST_P ( DisplayListTest  ,
DispatcherDoesNotCullPerspectiveTransformedChildDisplayLists   
)

Definition at line 913 of file dl_unittests.cc.

914  {
915  // Regression test for https://github.com/flutter/flutter/issues/130613
916  flutter::DisplayListBuilder sub_builder(true);
917  sub_builder.DrawRect(SkRect::MakeXYWH(0, 0, 50, 50),
918  flutter::DlPaint(flutter::DlColor::kRed()));
919  auto display_list = sub_builder.Build();
920 
921  DlDispatcher dispatcher(Rect::MakeLTRB(0, 0, 2400, 1800));
922  dispatcher.scale(2.0, 2.0);
923  dispatcher.translate(-93.0, 0.0);
924  // clang-format off
925  dispatcher.transformFullPerspective(
926  0.8, -0.2, -0.1, -0.0,
927  0.0, 1.0, 0.0, 0.0,
928  1.4, 1.3, 1.0, 0.0,
929  63.2, 65.3, 48.6, 1.1
930  );
931  // clang-format on
932  dispatcher.translate(35.0, 75.0);
933  dispatcher.drawDisplayList(display_list, 1.0f);
934  auto picture = dispatcher.EndRecordingAsPicture();
935 
936  bool found = false;
937  picture.pass->IterateAllEntities([&found](Entity& entity) {
938  if (std::static_pointer_cast<SolidColorContents>(entity.GetContents())
939  ->GetColor() == Color::Red()) {
940  found = true;
941  return false;
942  }
943 
944  return true;
945  });
946  EXPECT_TRUE(found);
947 }

References impeller::DlDispatcherBase::drawDisplayList(), impeller::DlDispatcherBase::EndRecordingAsPicture(), impeller::Entity::GetContents(), impeller::TRect< Scalar >::MakeLTRB(), impeller::Picture::pass, impeller::Color::Red(), impeller::DlDispatcherBase::scale(), impeller::DlDispatcherBase::transformFullPerspective(), and impeller::DlDispatcherBase::translate().

◆ TEST_P() [297/456]

impeller::testing::TEST_P ( DisplayListTest  ,
DrawMaskBlursThatMightUseSaveLayers   
)

Definition at line 1655 of file dl_unittests.cc.

1655  {
1656  flutter::DisplayListBuilder builder;
1657  builder.DrawColor(flutter::DlColor::kWhite(), flutter::DlBlendMode::kSrc);
1658  Vector2 scale = GetContentScale();
1659  builder.Scale(scale.x, scale.y);
1660 
1661  builder.Save();
1662  // We need a small transform op to avoid a deferred save
1663  builder.Translate(1.0f, 1.0f);
1664  auto solid_filter =
1665  flutter::DlBlurMaskFilter::Make(flutter::DlBlurStyle::kSolid, 5.0f);
1666  flutter::DlPaint solid_alpha_paint =
1667  flutter::DlPaint() //
1668  .setMaskFilter(solid_filter) //
1669  .setColor(flutter::DlColor::kBlue()) //
1670  .setAlpha(0x7f);
1671  for (int x = 1; x <= 4; x++) {
1672  for (int y = 1; y <= 4; y++) {
1673  builder.DrawRect(SkRect::MakeXYWH(x * 100, y * 100, 80, 80),
1674  solid_alpha_paint);
1675  }
1676  }
1677  builder.Restore();
1678 
1679  builder.Save();
1680  builder.Translate(500.0f, 0.0f);
1681  auto normal_filter =
1682  flutter::DlBlurMaskFilter::Make(flutter::DlBlurStyle::kNormal, 5.0f);
1683  auto rotate_if = flutter::DlMatrixImageFilter::Make(
1684  SkMatrix::RotateDeg(10), flutter::DlImageSampling::kLinear);
1685  flutter::DlPaint normal_if_paint =
1686  flutter::DlPaint() //
1687  .setMaskFilter(solid_filter) //
1688  .setImageFilter(rotate_if) //
1689  .setColor(flutter::DlColor::kGreen()) //
1690  .setAlpha(0x7f);
1691  for (int x = 1; x <= 4; x++) {
1692  for (int y = 1; y <= 4; y++) {
1693  builder.DrawRect(SkRect::MakeXYWH(x * 100, y * 100, 80, 80),
1694  normal_if_paint);
1695  }
1696  }
1697  builder.Restore();
1698 
1699  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1700 }

References scale.

◆ TEST_P() [298/456]

impeller::testing::TEST_P ( DisplayListTest  ,
DrawPaintIgnoresMaskFilter   
)

Definition at line 1632 of file dl_unittests.cc.

1632  {
1633  flutter::DisplayListBuilder builder;
1634  builder.DrawPaint(flutter::DlPaint().setColor(flutter::DlColor::kWhite()));
1635 
1636  auto filter = flutter::DlBlurMaskFilter(flutter::DlBlurStyle::kNormal, 10.0f);
1637  builder.DrawCircle({300, 300}, 200,
1638  flutter::DlPaint().setMaskFilter(&filter));
1639 
1640  std::vector<flutter::DlColor> colors = {flutter::DlColor::kGreen(),
1641  flutter::DlColor::kGreen()};
1642  const float stops[2] = {0.0, 1.0};
1643  auto linear = flutter::DlColorSource::MakeLinear(
1644  {100.0, 100.0}, {300.0, 300.0}, 2, colors.data(), stops,
1645  flutter::DlTileMode::kRepeat);
1646  flutter::DlPaint blend_paint =
1647  flutter::DlPaint() //
1648  .setColorSource(linear) //
1649  .setBlendMode(flutter::DlBlendMode::kScreen);
1650  builder.DrawPaint(blend_paint);
1651 
1652  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1653 }

◆ TEST_P() [299/456]

impeller::testing::TEST_P ( DisplayListTest  ,
DrawShapes   
)

Definition at line 1355 of file dl_unittests.cc.

1355  {
1356  flutter::DisplayListBuilder builder;
1357  std::vector<flutter::DlStrokeJoin> joins = {
1358  flutter::DlStrokeJoin::kBevel,
1359  flutter::DlStrokeJoin::kRound,
1360  flutter::DlStrokeJoin::kMiter,
1361  };
1362  flutter::DlPaint paint = //
1363  flutter::DlPaint() //
1364  .setColor(flutter::DlColor::kWhite()) //
1365  .setDrawStyle(flutter::DlDrawStyle::kFill) //
1366  .setStrokeWidth(10);
1367  flutter::DlPaint stroke_paint = //
1368  flutter::DlPaint() //
1369  .setColor(flutter::DlColor::kWhite()) //
1370  .setDrawStyle(flutter::DlDrawStyle::kStroke) //
1371  .setStrokeWidth(10);
1372  SkPath path = SkPath().addPoly({{150, 50}, {160, 50}}, false);
1373 
1374  builder.Translate(300, 50);
1375  builder.Scale(0.8, 0.8);
1376  for (auto join : joins) {
1377  paint.setStrokeJoin(join);
1378  stroke_paint.setStrokeJoin(join);
1379  builder.DrawRect(SkRect::MakeXYWH(0, 0, 100, 100), paint);
1380  builder.DrawRect(SkRect::MakeXYWH(0, 150, 100, 100), stroke_paint);
1381  builder.DrawRRect(
1382  SkRRect::MakeRectXY(SkRect::MakeXYWH(150, 0, 100, 100), 30, 30), paint);
1383  builder.DrawRRect(
1384  SkRRect::MakeRectXY(SkRect::MakeXYWH(150, 150, 100, 100), 30, 30),
1385  stroke_paint);
1386  builder.DrawCircle({350, 50}, 50, paint);
1387  builder.DrawCircle({350, 200}, 50, stroke_paint);
1388  builder.Translate(0, 300);
1389  }
1390  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1391 }

References paint.

◆ TEST_P() [300/456]

impeller::testing::TEST_P ( DisplayListTest  ,
DrawVerticesBlendModes   
)

Definition at line 1455 of file dl_unittests.cc.

1455  {
1456  std::vector<const char*> blend_mode_names;
1457  std::vector<flutter::DlBlendMode> blend_mode_values;
1458  {
1459  const std::vector<std::tuple<const char*, flutter::DlBlendMode>> blends = {
1460  // Pipeline blends (Porter-Duff alpha compositing)
1461  {"Clear", flutter::DlBlendMode::kClear},
1462  {"Source", flutter::DlBlendMode::kSrc},
1463  {"Destination", flutter::DlBlendMode::kDst},
1464  {"SourceOver", flutter::DlBlendMode::kSrcOver},
1465  {"DestinationOver", flutter::DlBlendMode::kDstOver},
1466  {"SourceIn", flutter::DlBlendMode::kSrcIn},
1467  {"DestinationIn", flutter::DlBlendMode::kDstIn},
1468  {"SourceOut", flutter::DlBlendMode::kSrcOut},
1469  {"DestinationOut", flutter::DlBlendMode::kDstOut},
1470  {"SourceATop", flutter::DlBlendMode::kSrcATop},
1471  {"DestinationATop", flutter::DlBlendMode::kDstATop},
1472  {"Xor", flutter::DlBlendMode::kXor},
1473  {"Plus", flutter::DlBlendMode::kPlus},
1474  {"Modulate", flutter::DlBlendMode::kModulate},
1475  // Advanced blends (color component blends)
1476  {"Screen", flutter::DlBlendMode::kScreen},
1477  {"Overlay", flutter::DlBlendMode::kOverlay},
1478  {"Darken", flutter::DlBlendMode::kDarken},
1479  {"Lighten", flutter::DlBlendMode::kLighten},
1480  {"ColorDodge", flutter::DlBlendMode::kColorDodge},
1481  {"ColorBurn", flutter::DlBlendMode::kColorBurn},
1482  {"HardLight", flutter::DlBlendMode::kHardLight},
1483  {"SoftLight", flutter::DlBlendMode::kSoftLight},
1484  {"Difference", flutter::DlBlendMode::kDifference},
1485  {"Exclusion", flutter::DlBlendMode::kExclusion},
1486  {"Multiply", flutter::DlBlendMode::kMultiply},
1487  {"Hue", flutter::DlBlendMode::kHue},
1488  {"Saturation", flutter::DlBlendMode::kSaturation},
1489  {"Color", flutter::DlBlendMode::kColor},
1490  {"Luminosity", flutter::DlBlendMode::kLuminosity},
1491  };
1492  assert(blends.size() ==
1493  static_cast<size_t>(flutter::DlBlendMode::kLastMode) + 1);
1494  for (const auto& [name, mode] : blends) {
1495  blend_mode_names.push_back(name);
1496  blend_mode_values.push_back(mode);
1497  }
1498  }
1499 
1500  auto callback = [&]() {
1501  static int current_blend_index = 3;
1502  static float dst_alpha = 1;
1503  static float src_alpha = 1;
1504  static float color0[4] = {1.0f, 0.0f, 0.0f, 1.0f};
1505  static float color1[4] = {0.0f, 1.0f, 0.0f, 1.0f};
1506  static float color2[4] = {0.0f, 0.0f, 1.0f, 1.0f};
1507  static float src_color[4] = {1.0f, 1.0f, 1.0f, 1.0f};
1508 
1509  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
1510  {
1511  ImGui::ListBox("Blending mode", &current_blend_index,
1512  blend_mode_names.data(), blend_mode_names.size());
1513  ImGui::SliderFloat("Source alpha", &src_alpha, 0, 1);
1514  ImGui::ColorEdit4("Color A", color0);
1515  ImGui::ColorEdit4("Color B", color1);
1516  ImGui::ColorEdit4("Color C", color2);
1517  ImGui::ColorEdit4("Source Color", src_color);
1518  ImGui::SliderFloat("Destination alpha", &dst_alpha, 0, 1);
1519  }
1520  ImGui::End();
1521 
1522  std::vector<SkPoint> positions = {SkPoint::Make(100, 300),
1523  SkPoint::Make(200, 100),
1524  SkPoint::Make(300, 300)};
1525  std::vector<flutter::DlColor> colors = {
1526  toColor(color0).modulateOpacity(dst_alpha),
1527  toColor(color1).modulateOpacity(dst_alpha),
1528  toColor(color2).modulateOpacity(dst_alpha)};
1529 
1530  auto vertices = flutter::DlVertices::Make(
1531  flutter::DlVertexMode::kTriangles, 3, positions.data(),
1532  /*texture_coordinates=*/nullptr, colors.data());
1533 
1534  flutter::DisplayListBuilder builder;
1535  flutter::DlPaint paint;
1536 
1537  paint.setColor(toColor(src_color).modulateOpacity(src_alpha));
1538  builder.DrawVertices(vertices, blend_mode_values[current_blend_index],
1539  paint);
1540  return builder.Build();
1541  };
1542 
1543  ASSERT_TRUE(OpenPlaygroundHere(callback));
1544 }

References paint, and toColor().

◆ TEST_P() [301/456]

impeller::testing::TEST_P ( DisplayListTest  ,
IgnoreMaskFilterWhenSavingLayer   
)

Definition at line 505 of file dl_unittests.cc.

505  {
506  auto texture = CreateTextureForFixture("embarcadero.jpg");
507  flutter::DisplayListBuilder builder;
508  auto filter = flutter::DlBlurMaskFilter(flutter::DlBlurStyle::kNormal, 10.0f);
509  flutter::DlPaint paint;
510  paint.setMaskFilter(&filter);
511  builder.SaveLayer(nullptr, &paint);
512  builder.DrawImage(DlImageImpeller::Make(texture), SkPoint::Make(100, 100),
513  flutter::DlImageSampling::kNearestNeighbor);
514  builder.Restore();
515  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
516 }

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

◆ TEST_P() [302/456]

impeller::testing::TEST_P ( DisplayListTest  ,
MaskBlursApplyCorrectlyToColorSources   
)

Definition at line 1318 of file dl_unittests.cc.

1318  {
1319  auto blur_filter = std::make_shared<flutter::DlBlurMaskFilter>(
1320  flutter::DlBlurStyle::kNormal, 10);
1321 
1322  flutter::DisplayListBuilder builder;
1323 
1324  std::array<flutter::DlColor, 2> colors = {flutter::DlColor::kBlue(),
1325  flutter::DlColor::kGreen()};
1326  std::array<float, 2> stops = {0, 1};
1327  std::array<std::shared_ptr<flutter::DlColorSource>, 2> color_sources = {
1328  std::make_shared<flutter::DlColorColorSource>(flutter::DlColor::kWhite()),
1329  flutter::DlColorSource::MakeLinear(
1330  SkPoint::Make(0, 0), SkPoint::Make(100, 50), 2, colors.data(),
1331  stops.data(), flutter::DlTileMode::kClamp)};
1332 
1333  int offset = 100;
1334  for (const auto& color_source : color_sources) {
1335  flutter::DlPaint paint;
1336  paint.setColorSource(color_source);
1337  paint.setMaskFilter(blur_filter);
1338 
1339  paint.setDrawStyle(flutter::DlDrawStyle::kFill);
1340  builder.DrawRRect(
1341  SkRRect::MakeRectXY(SkRect::MakeXYWH(100, offset, 100, 50), 30, 30),
1342  paint);
1343  paint.setDrawStyle(flutter::DlDrawStyle::kStroke);
1344  paint.setStrokeWidth(10);
1345  builder.DrawRRect(
1346  SkRRect::MakeRectXY(SkRect::MakeXYWH(300, offset, 100, 50), 30, 30),
1347  paint);
1348 
1349  offset += 100;
1350  }
1351 
1352  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1353 }

References offset, and paint.

◆ TEST_P() [303/456]

impeller::testing::TEST_P ( DisplayListTest  ,
NinePatchImagePrecision   
)

Definition at line 793 of file dl_unittests.cc.

793  {
794  // Draw a nine patch image with colored corners and verify that the corner
795  // color does not leak outside the intended region.
796  auto texture = CreateTextureForFixture("nine_patch_corners.png");
797  flutter::DisplayListBuilder builder;
798  builder.DrawImageNine(DlImageImpeller::Make(texture),
799  SkIRect::MakeXYWH(10, 10, 1, 1),
800  SkRect::MakeXYWH(0, 0, 200, 100),
801  flutter::DlFilterMode::kNearest, nullptr);
802  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
803 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [304/456]

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(SkRect::MakeSize({100, 100}), paint);
275 
276  // Rounded rectangle
277  builder.Translate(150, 0);
278  builder.DrawRRect(SkRRect::MakeRectXY(SkRect::MakeSize({100, 50}), 10, 10),
279  paint);
280 
281  // Double rounded rectangle
282  builder.Translate(150, 0);
283  builder.DrawDRRect(
284  SkRRect::MakeRectXY(SkRect::MakeSize({100, 50}), 10, 10),
285  SkRRect::MakeRectXY(SkRect::MakeXYWH(10, 10, 80, 30), 10, 10), paint);
286 
287  // Contour with duplicate join points
288  {
289  builder.Translate(150, 0);
290  SkPath path;
291  path.moveTo(0, 0);
292  path.lineTo(0, 0);
293  path.lineTo({100, 0});
294  path.lineTo({100, 0});
295  path.lineTo({100, 100});
296  builder.DrawPath(path, paint);
297  }
298 
299  // Contour with duplicate start and end points
300 
301  // Line.
302  builder.Translate(200, 0);
303  {
304  builder.Save();
305 
306  SkPath line_path;
307  line_path.moveTo(0, 0);
308  line_path.moveTo(0, 0);
309  line_path.lineTo({0, 0});
310  line_path.lineTo({0, 0});
311  line_path.lineTo({50, 50});
312  line_path.lineTo({50, 50});
313  line_path.lineTo({100, 0});
314  line_path.lineTo({100, 0});
315  builder.DrawPath(line_path, paint);
316 
317  builder.Translate(0, 100);
318  builder.DrawPath(line_path, paint);
319 
320  builder.Translate(0, 100);
321  SkPath line_path2;
322  line_path2.moveTo(0, 0);
323  line_path2.lineTo(0, 0);
324  line_path2.lineTo(0, 0);
325  builder.DrawPath(line_path2, paint);
326 
327  builder.Restore();
328  }
329 
330  // Cubic.
331  builder.Translate(150, 0);
332  {
333  builder.Save();
334 
335  SkPath cubic_path;
336  cubic_path.moveTo({0, 0});
337  cubic_path.cubicTo(0, 0, 140.0, 100.0, 140, 20);
338  builder.DrawPath(cubic_path, paint);
339 
340  builder.Translate(0, 100);
341  SkPath cubic_path2;
342  cubic_path2.moveTo({0, 0});
343  cubic_path2.cubicTo(0, 0, 0, 0, 150, 150);
344  builder.DrawPath(cubic_path2, paint);
345 
346  builder.Translate(0, 100);
347  SkPath cubic_path3;
348  cubic_path3.moveTo({0, 0});
349  cubic_path3.cubicTo(0, 0, 0, 0, 0, 0);
350  builder.DrawPath(cubic_path3, paint);
351 
352  builder.Restore();
353  }
354 
355  // Quad.
356  builder.Translate(200, 0);
357  {
358  builder.Save();
359 
360  SkPath quad_path;
361  quad_path.moveTo(0, 0);
362  quad_path.moveTo(0, 0);
363  quad_path.quadTo({100, 40}, {50, 80});
364  builder.DrawPath(quad_path, paint);
365 
366  builder.Translate(0, 150);
367  SkPath quad_path2;
368  quad_path2.moveTo(0, 0);
369  quad_path2.moveTo(0, 0);
370  quad_path2.quadTo({0, 0}, {100, 100});
371  builder.DrawPath(quad_path2, paint);
372 
373  builder.Translate(0, 100);
374  SkPath quad_path3;
375  quad_path3.moveTo(0, 0);
376  quad_path3.quadTo({0, 0}, {0, 0});
377  builder.DrawPath(quad_path3, paint);
378 
379  builder.Restore();
380  }
381  return builder.Build();
382  };
383  ASSERT_TRUE(OpenPlaygroundHere(callback));
384 }

References paint, and stroke_width.

◆ TEST_P() [305/456]

impeller::testing::TEST_P ( DisplayListTest  ,
StrokedTextNotOffsetFromNormalText   
)

Definition at line 480 of file dl_unittests.cc.

480  {
481  flutter::DisplayListBuilder builder;
482  flutter::DlPaint paint;
483  auto const& text_blob = SkTextBlob::MakeFromString("00000", CreateTestFont());
484 
485  // https://api.flutter.dev/flutter/material/Colors/blue-constant.html.
486  auto const& mat_blue = flutter::DlColor(0xFF2196f3);
487 
488  // Draw a blue filled rectangle so the text is easier to see.
489  paint.setDrawStyle(flutter::DlDrawStyle::kFill);
490  paint.setColor(mat_blue);
491  builder.DrawRect(SkRect::MakeXYWH(0, 0, 500, 500), paint);
492 
493  // Draw stacked text, with stroked text on top.
494  paint.setDrawStyle(flutter::DlDrawStyle::kFill);
495  paint.setColor(flutter::DlColor::kWhite());
496  builder.DrawTextBlob(text_blob, 250, 250, paint);
497 
498  paint.setDrawStyle(flutter::DlDrawStyle::kStroke);
499  paint.setColor(flutter::DlColor::kBlack());
500  builder.DrawTextBlob(text_blob, 250, 250, paint);
501 
502  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
503 }

References paint.

◆ TEST_P() [306/456]

impeller::testing::TEST_P ( DisplayListTest  ,
TransparentShadowProducesCorrectColor   
)

Definition at line 949 of file dl_unittests.cc.

949  {
950  DlDispatcher dispatcher;
951  dispatcher.save();
952  dispatcher.scale(1.618, 1.618);
953  SkPath path = SkPath{}.addRect(SkRect::MakeXYWH(0, 0, 200, 100));
954  flutter::DlOpReceiver::CacheablePath cache(path);
955  dispatcher.drawShadow(cache, flutter::DlColor::kTransparent(), 15, false, 1);
956  dispatcher.restore();
957  auto picture = dispatcher.EndRecordingAsPicture();
958 
959  std::shared_ptr<SolidRRectBlurContents> rrect_blur;
960  picture.pass->IterateAllEntities([&rrect_blur](Entity& entity) {
961  if (ScalarNearlyEqual(entity.GetTransform().GetScale().x, 1.618f)) {
962  rrect_blur = std::static_pointer_cast<SolidRRectBlurContents>(
963  entity.GetContents());
964  return false;
965  }
966  return true;
967  });
968 
969  ASSERT_NE(rrect_blur, nullptr);
970  ASSERT_EQ(rrect_blur->GetColor().red, 0);
971  ASSERT_EQ(rrect_blur->GetColor().green, 0);
972  ASSERT_EQ(rrect_blur->GetColor().blue, 0);
973  ASSERT_EQ(rrect_blur->GetColor().alpha, 0);
974 }

References impeller::DlDispatcherBase::drawShadow(), impeller::DlDispatcherBase::EndRecordingAsPicture(), impeller::Matrix::GetScale(), impeller::Entity::GetTransform(), impeller::Picture::pass, impeller::DlDispatcherBase::restore(), impeller::DlDispatcher::save(), impeller::ScalarNearlyEqual(), impeller::DlDispatcherBase::scale(), and impeller::Vector3::x.

◆ TEST_P() [307/456]

impeller::testing::TEST_P ( DriverInfoVKTest  ,
CanDumpToLog   
)

Definition at line 26 of file driver_info_vk_unittests.cc.

26  {
27  ASSERT_TRUE(GetContext());
28  const auto& driver_info =
29  SurfaceContextVK::Cast(*GetContext()).GetParent()->GetDriverInfo();
30  ASSERT_NE(driver_info, nullptr);
31  fml::testing::LogCapture log;
32  driver_info->DumpToLog();
33  ASSERT_TRUE(log.str().find("Driver Information") != std::string::npos);
34 }

References impeller::BackendCast< SurfaceContextVK, Context >::Cast(), and impeller::SurfaceContextVK::GetParent().

◆ TEST_P() [308/456]

impeller::testing::TEST_P ( DriverInfoVKTest  ,
CanQueryDriverInfo   
)

Definition at line 14 of file driver_info_vk_unittests.cc.

14  {
15  ASSERT_TRUE(GetContext());
16  const auto& driver_info =
17  SurfaceContextVK::Cast(*GetContext()).GetParent()->GetDriverInfo();
18  ASSERT_NE(driver_info, nullptr);
19  // 1.1 is the base Impeller version. The driver can't be lower than that.
20  ASSERT_TRUE(driver_info->GetAPIVersion().IsAtLeast(Version{1, 1, 0}));
21  ASSERT_NE(driver_info->GetVendor(), VendorVK::kUnknown);
22  ASSERT_NE(driver_info->GetDeviceType(), DeviceTypeVK::kUnknown);
23  ASSERT_NE(driver_info->GetDriverName(), "");
24 }

References impeller::BackendCast< SurfaceContextVK, Context >::Cast(), impeller::SurfaceContextVK::GetParent(), and impeller::kUnknown.

◆ TEST_P() [309/456]

impeller::testing::TEST_P ( EntityPassTargetTest  ,
SwapWithMSAAImplicitResolve   
)

Definition at line 53 of file entity_pass_target_unittests.cc.

53  {
54  auto content_context = GetContentContext();
55  auto buffer = content_context->GetContext()->CreateCommandBuffer();
56  auto context = content_context->GetContext();
57  auto& allocator = *context->GetResourceAllocator();
58 
59  // Emulate implicit MSAA resolve by making color resolve and msaa texture the
60  // same.
61  RenderTarget render_target;
62  {
63  PixelFormat pixel_format =
64  context->GetCapabilities()->GetDefaultColorFormat();
65 
66  // Create MSAA color texture.
67 
68  TextureDescriptor color0_tex_desc;
69  color0_tex_desc.storage_mode = StorageMode::kDevicePrivate;
70  color0_tex_desc.type = TextureType::kTexture2DMultisample;
71  color0_tex_desc.sample_count = SampleCount::kCount4;
72  color0_tex_desc.format = pixel_format;
73  color0_tex_desc.size = ISize{100, 100};
74  color0_tex_desc.usage = TextureUsage::kRenderTarget;
75 
76  auto color0_msaa_tex = allocator.CreateTexture(color0_tex_desc);
77 
78  // Color attachment.
79 
80  ColorAttachment color0;
81  color0.load_action = LoadAction::kDontCare;
82  color0.store_action = StoreAction::kStoreAndMultisampleResolve;
83  color0.texture = color0_msaa_tex;
84  color0.resolve_texture = color0_msaa_tex;
85 
86  render_target.SetColorAttachment(color0, 0u);
87  render_target.SetStencilAttachment(std::nullopt);
88  }
89 
90  auto entity_pass_target = EntityPassTarget(render_target, false, true);
91 
92  auto color0 = entity_pass_target.GetRenderTarget()
93  .GetColorAttachments()
94  .find(0u)
95  ->second;
96  auto msaa_tex = color0.texture;
97  auto resolve_tex = color0.resolve_texture;
98 
99  ASSERT_EQ(msaa_tex, resolve_tex);
100 
101  entity_pass_target.Flip(
102  *content_context->GetContext()->GetResourceAllocator());
103 
104  color0 = entity_pass_target.GetRenderTarget()
105  .GetColorAttachments()
106  .find(0u)
107  ->second;
108 
109  ASSERT_NE(msaa_tex, color0.texture);
110  ASSERT_NE(resolve_tex, color0.resolve_texture);
111  ASSERT_EQ(color0.texture, color0.resolve_texture);
112 }

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

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()
35  .GetColorAttachments()
36  .find(0u)
37  ->second;
38  auto msaa_tex = color0.texture;
39  auto resolve_tex = color0.resolve_texture;
40 
41  entity_pass_target.Flip(
42  *content_context->GetContext()->GetResourceAllocator());
43 
44  color0 = entity_pass_target.GetRenderTarget()
45  .GetColorAttachments()
46  .find(0u)
47  ->second;
48 
49  ASSERT_EQ(msaa_tex, color0.texture);
50  ASSERT_NE(resolve_tex, color0.resolve_texture);
51 }

◆ TEST_P() [311/456]

impeller::testing::TEST_P ( EntityTest  ,
AdvancedBlendCoverageHintIsNotResetByEntityPass   
)

Definition at line 2370 of file entity_unittests.cc.

2370  {
2371  if (GetContext()->GetCapabilities()->SupportsFramebufferFetch()) {
2372  GTEST_SKIP() << "Backends that support framebuffer fetch dont use coverage "
2373  "for advanced blends.";
2374  }
2375 
2376  auto contents = std::make_shared<SolidColorContents>();
2377  contents->SetGeometry(Geometry::MakeRect(Rect::MakeXYWH(100, 100, 100, 100)));
2378  contents->SetColor(Color::Red());
2379 
2380  Entity entity;
2381  entity.SetTransform(Matrix::MakeScale(Vector3(2, 2, 1)));
2382  entity.SetBlendMode(BlendMode::kColorBurn);
2383  entity.SetContents(contents);
2384 
2385  auto coverage = entity.GetCoverage();
2386  EXPECT_TRUE(coverage.has_value());
2387 
2388  auto pass = std::make_unique<EntityPass>();
2389  std::shared_ptr<RenderTargetCache> render_target_allocator =
2390  std::make_shared<RenderTargetCache>(GetContext()->GetResourceAllocator());
2391  auto stencil_config = RenderTarget::AttachmentConfig{
2392  .storage_mode = StorageMode::kDevicePrivate,
2393  .load_action = LoadAction::kClear,
2394  .store_action = StoreAction::kDontCare,
2395  .clear_color = Color::BlackTransparent()};
2396  auto rt = render_target_allocator->CreateOffscreen(
2397  *GetContext(), ISize::MakeWH(1000, 1000),
2398  /*mip_count=*/1, "Offscreen", RenderTarget::kDefaultColorAttachmentConfig,
2399  stencil_config);
2400  auto content_context = ContentContext(
2401  GetContext(), TypographerContextSkia::Make(), render_target_allocator);
2402  pass->AddEntity(std::move(entity));
2403 
2404  EXPECT_TRUE(pass->Render(content_context, rt));
2405 
2406  auto contains_size = [&render_target_allocator](ISize size) -> bool {
2407  return std::find_if(render_target_allocator->GetRenderTargetDataBegin(),
2408  render_target_allocator->GetRenderTargetDataEnd(),
2409  [&size](const auto& data) {
2410  return data.config.size == size;
2411  }) != render_target_allocator->GetRenderTargetDataEnd();
2412  };
2413 
2414  EXPECT_TRUE(contains_size(ISize(1000, 1000)))
2415  << "The root texture wasn't allocated";
2416  EXPECT_TRUE(contains_size(ISize(200, 200)))
2417  << "The ColorBurned texture wasn't allocated (100x100 scales up 2x)";
2418 }

References impeller::Color::BlackTransparent(), data, impeller::Entity::GetCoverage(), impeller::kClear, impeller::kColorBurn, impeller::RenderTarget::kDefaultColorAttachmentConfig, impeller::kDevicePrivate, impeller::kDontCare, impeller::TypographerContextSkia::Make(), impeller::Geometry::MakeRect(), impeller::Matrix::MakeScale(), impeller::TSize< T >::MakeWH(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Color::Red(), impeller::Entity::SetBlendMode(), impeller::Entity::SetContents(), impeller::Entity::SetTransform(), and impeller::RenderTarget::AttachmentConfig::storage_mode.

◆ TEST_P() [312/456]

impeller::testing::TEST_P ( EntityTest  ,
BezierCircleScaled   
)

Definition at line 993 of file entity_unittests.cc.

993  {
994  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
995  static float scale = 20;
996 
997  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
998  ImGui::SliderFloat("Scale", &scale, 1, 100);
999  ImGui::End();
1000 
1001  Entity entity;
1002  entity.SetTransform(Matrix::MakeScale(GetContentScale()));
1003  auto path = PathBuilder{}
1004  .MoveTo({97.325, 34.818})
1005  .CubicCurveTo({98.50862885295136, 34.81812293973836},
1006  {99.46822048142015, 33.85863261475589},
1007  {99.46822048142015, 32.67499810206613})
1008  .CubicCurveTo({99.46822048142015, 31.491363589376355},
1009  {98.50862885295136, 30.53187326439389},
1010  {97.32499434685802, 30.531998226542708})
1011  .CubicCurveTo({96.14153655073771, 30.532123170035373},
1012  {95.18222070648729, 31.491540299350355},
1013  {95.18222070648729, 32.67499810206613})
1014  .CubicCurveTo({95.18222070648729, 33.85845590478189},
1015  {96.14153655073771, 34.81787303409686},
1016  {97.32499434685802, 34.81799797758954})
1017  .Close()
1018  .TakePath();
1019  entity.SetTransform(
1020  Matrix::MakeScale({scale, scale, 1.0}).Translate({-90, -20, 0}));
1021  entity.SetContents(SolidColorContents::Make(path, Color::Red()));
1022  return entity.Render(context, pass);
1023  };
1024  ASSERT_TRUE(OpenPlaygroundHere(callback));
1025 }

References impeller::Close(), impeller::SolidColorContents::Make(), impeller::Matrix::MakeScale(), impeller::PathBuilder::MoveTo(), impeller::Color::Red(), impeller::Entity::Render(), scale, impeller::Entity::SetContents(), and impeller::Entity::SetTransform().

◆ TEST_P() [313/456]

impeller::testing::TEST_P ( EntityTest  ,
BlendingModeOptions   
)

Definition at line 862 of file entity_unittests.cc.

862  {
863  std::vector<const char*> blend_mode_names;
864  std::vector<BlendMode> blend_mode_values;
865  {
866  // Force an exhausiveness check with a switch. When adding blend modes,
867  // update this switch with a new name/value to make it selectable in the
868  // test GUI.
869 
870  const BlendMode b{};
871  static_assert(b == BlendMode::kClear); // Ensure the first item in
872  // the switch is the first
873  // item in the enum.
874  static_assert(Entity::kLastPipelineBlendMode == BlendMode::kModulate);
875  switch (b) {
876  case BlendMode::kClear:
877  blend_mode_names.push_back("Clear");
878  blend_mode_values.push_back(BlendMode::kClear);
879  case BlendMode::kSource:
880  blend_mode_names.push_back("Source");
881  blend_mode_values.push_back(BlendMode::kSource);
882  case BlendMode::kDestination:
883  blend_mode_names.push_back("Destination");
884  blend_mode_values.push_back(BlendMode::kDestination);
885  case BlendMode::kSourceOver:
886  blend_mode_names.push_back("SourceOver");
887  blend_mode_values.push_back(BlendMode::kSourceOver);
888  case BlendMode::kDestinationOver:
889  blend_mode_names.push_back("DestinationOver");
890  blend_mode_values.push_back(BlendMode::kDestinationOver);
891  case BlendMode::kSourceIn:
892  blend_mode_names.push_back("SourceIn");
893  blend_mode_values.push_back(BlendMode::kSourceIn);
894  case BlendMode::kDestinationIn:
895  blend_mode_names.push_back("DestinationIn");
896  blend_mode_values.push_back(BlendMode::kDestinationIn);
897  case BlendMode::kSourceOut:
898  blend_mode_names.push_back("SourceOut");
899  blend_mode_values.push_back(BlendMode::kSourceOut);
900  case BlendMode::kDestinationOut:
901  blend_mode_names.push_back("DestinationOut");
902  blend_mode_values.push_back(BlendMode::kDestinationOut);
903  case BlendMode::kSourceATop:
904  blend_mode_names.push_back("SourceATop");
905  blend_mode_values.push_back(BlendMode::kSourceATop);
906  case BlendMode::kDestinationATop:
907  blend_mode_names.push_back("DestinationATop");
908  blend_mode_values.push_back(BlendMode::kDestinationATop);
909  case BlendMode::kXor:
910  blend_mode_names.push_back("Xor");
911  blend_mode_values.push_back(BlendMode::kXor);
912  case BlendMode::kPlus:
913  blend_mode_names.push_back("Plus");
914  blend_mode_values.push_back(BlendMode::kPlus);
915  case BlendMode::kModulate:
916  blend_mode_names.push_back("Modulate");
917  blend_mode_values.push_back(BlendMode::kModulate);
918  };
919  }
920 
921  auto callback = [&](ContentContext& context, RenderPass& pass) {
922  auto world_matrix = Matrix::MakeScale(GetContentScale());
923  auto draw_rect = [&context, &pass, &world_matrix](
924  Rect rect, Color color, BlendMode blend_mode) -> bool {
925  using VS = SolidFillPipeline::VertexShader;
926  using FS = SolidFillPipeline::FragmentShader;
927 
928  VertexBufferBuilder<VS::PerVertexData> vtx_builder;
929  {
930  auto r = rect.GetLTRB();
931  vtx_builder.AddVertices({
932  {Point(r[0], r[1])},
933  {Point(r[2], r[1])},
934  {Point(r[2], r[3])},
935  {Point(r[0], r[1])},
936  {Point(r[2], r[3])},
937  {Point(r[0], r[3])},
938  });
939  }
940 
941  pass.SetCommandLabel("Blended Rectangle");
942  auto options = OptionsFromPass(pass);
943  options.blend_mode = blend_mode;
944  options.primitive_type = PrimitiveType::kTriangle;
945  pass.SetPipeline(context.GetSolidFillPipeline(options));
946  pass.SetVertexBuffer(
947  vtx_builder.CreateVertexBuffer(context.GetTransientsBuffer()));
948 
949  VS::FrameInfo frame_info;
950  frame_info.mvp = pass.GetOrthographicTransform() * world_matrix;
951  VS::BindFrameInfo(
952  pass, context.GetTransientsBuffer().EmplaceUniform(frame_info));
953  FS::FragInfo frag_info;
954  frag_info.color = color.Premultiply();
955  FS::BindFragInfo(
956  pass, context.GetTransientsBuffer().EmplaceUniform(frame_info));
957  return pass.Draw().ok();
958  };
959 
960  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
961  static Color color1(1, 0, 0, 0.5), color2(0, 1, 0, 0.5);
962  ImGui::ColorEdit4("Color 1", reinterpret_cast<float*>(&color1));
963  ImGui::ColorEdit4("Color 2", reinterpret_cast<float*>(&color2));
964  static int current_blend_index = 3;
965  ImGui::ListBox("Blending mode", &current_blend_index,
966  blend_mode_names.data(), blend_mode_names.size());
967  ImGui::End();
968 
969  BlendMode selected_mode = blend_mode_values[current_blend_index];
970 
971  Point a, b, c, d;
972  static PlaygroundPoint point_a(Point(400, 100), 20, Color::White());
973  static PlaygroundPoint point_b(Point(200, 300), 20, Color::White());
974  std::tie(a, b) = DrawPlaygroundLine(point_a, point_b);
975  static PlaygroundPoint point_c(Point(470, 190), 20, Color::White());
976  static PlaygroundPoint point_d(Point(270, 390), 20, Color::White());
977  std::tie(c, d) = DrawPlaygroundLine(point_c, point_d);
978 
979  bool result = true;
980  result = result &&
981  draw_rect(Rect::MakeXYWH(0, 0, pass.GetRenderTargetSize().width,
982  pass.GetRenderTargetSize().height),
983  Color(), BlendMode::kClear);
984  result = result && draw_rect(Rect::MakeLTRB(a.x, a.y, b.x, b.y), color1,
985  BlendMode::kSourceOver);
986  result = result && draw_rect(Rect::MakeLTRB(c.x, c.y, d.x, d.y), color2,
987  selected_mode);
988  return result;
989  };
990  ASSERT_TRUE(OpenPlaygroundHere(callback));
991 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), impeller::saturated::b, color, impeller::VertexBufferBuilder< VertexType_, IndexType_ >::CreateVertexBuffer(), impeller::DrawPlaygroundLine(), impeller::HostBuffer::EmplaceUniform(), impeller::ContentContext::GetSolidFillPipeline(), impeller::ContentContext::GetTransientsBuffer(), impeller::kClear, impeller::kDestination, impeller::kDestinationATop, impeller::kDestinationIn, impeller::kDestinationOut, impeller::kDestinationOver, impeller::Entity::kLastPipelineBlendMode, impeller::kModulate, impeller::kPlus, impeller::kSource, impeller::kSourceATop, impeller::kSourceIn, impeller::kSourceOut, impeller::kSourceOver, 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() [314/456]

impeller::testing::TEST_P ( EntityTest  ,
BorderMaskBlurCoverageIsCorrect   
)

Definition at line 1394 of file entity_unittests.cc.

1394  {
1395  auto fill = std::make_shared<SolidColorContents>();
1396  fill->SetGeometry(Geometry::MakeFillPath(
1397  PathBuilder{}.AddRect(Rect::MakeXYWH(0, 0, 300, 400)).TakePath()));
1398  fill->SetColor(Color::CornflowerBlue());
1399  auto border_mask_blur = FilterContents::MakeBorderMaskBlur(
1400  FilterInput::Make(fill), Radius{3}, Radius{4});
1401 
1402  {
1403  Entity e;
1404  e.SetTransform(Matrix());
1405  auto actual = border_mask_blur->GetCoverage(e);
1406  auto expected = Rect::MakeXYWH(-3, -4, 306, 408);
1407  ASSERT_TRUE(actual.has_value());
1408  ASSERT_RECT_NEAR(actual.value(), expected);
1409  }
1410 
1411  {
1412  Entity e;
1413  e.SetTransform(Matrix::MakeRotationZ(Radians{kPi / 4}));
1414  auto actual = border_mask_blur->GetCoverage(e);
1415  auto expected = Rect::MakeXYWH(-287.792, -4.94975, 504.874, 504.874);
1416  ASSERT_TRUE(actual.has_value());
1417  ASSERT_RECT_NEAR(actual.value(), expected);
1418  }
1419 }

References impeller::PathBuilder::AddRect(), 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() [315/456]

impeller::testing::TEST_P ( EntityTest  ,
CanComputeGeometryForEmptyPathsWithoutCrashing   
)

Definition at line 2549 of file entity_unittests.cc.

2549  {
2550  PathBuilder builder = {};
2551  builder.AddRect(Rect::MakeLTRB(0, 0, 0, 0));
2552  Path path = builder.TakePath();
2553 
2554  EXPECT_TRUE(path.GetBoundingBox()->IsEmpty());
2555 
2556  auto geom = Geometry::MakeFillPath(path);
2557 
2558  Entity entity;
2559  RenderTarget target =
2560  GetContentContext()->GetRenderTargetCache()->CreateOffscreen(
2561  *GetContext(), {1, 1}, 1u);
2562  testing::MockRenderPass render_pass(GetContext(), target);
2563  auto position_result =
2564  geom->GetPositionBuffer(*GetContentContext(), entity, render_pass);
2565 
2566  EXPECT_EQ(position_result.vertex_buffer.vertex_count, 0u);
2567 
2568  EXPECT_EQ(geom->GetResultMode(), GeometryResult::Mode::kNormal);
2569 }

References impeller::PathBuilder::AddRect(), impeller::Path::GetBoundingBox(), impeller::GeometryResult::kNormal, impeller::Geometry::MakeFillPath(), impeller::TRect< Scalar >::MakeLTRB(), and impeller::PathBuilder::TakePath().

◆ TEST_P() [316/456]

impeller::testing::TEST_P ( EntityTest  ,
CanCreateEntity   
)

Definition at line 71 of file entity_unittests.cc.

71  {
72  Entity entity;
73  ASSERT_TRUE(entity.GetTransform().IsIdentity());
74 }

References impeller::Entity::GetTransform(), and impeller::Matrix::IsIdentity().

◆ TEST_P() [317/456]

impeller::testing::TEST_P ( EntityTest  ,
CanDrawCorrectlyWithRotatedTransform   
)

Definition at line 546 of file entity_unittests.cc.

546  {
547  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
548  const char* input_axis[] = {"X", "Y", "Z"};
549  static int rotation_axis_index = 0;
550  static float rotation = 0;
551  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
552  ImGui::SliderFloat("Rotation", &rotation, -kPi, kPi);
553  ImGui::Combo("Rotation Axis", &rotation_axis_index, input_axis,
554  sizeof(input_axis) / sizeof(char*));
555  Matrix rotation_matrix;
556  switch (rotation_axis_index) {
557  case 0:
558  rotation_matrix = Matrix::MakeRotationX(Radians(rotation));
559  break;
560  case 1:
561  rotation_matrix = Matrix::MakeRotationY(Radians(rotation));
562  break;
563  case 2:
564  rotation_matrix = Matrix::MakeRotationZ(Radians(rotation));
565  break;
566  default:
567  rotation_matrix = Matrix{};
568  break;
569  }
570 
571  if (ImGui::Button("Reset")) {
572  rotation = 0;
573  }
574  ImGui::End();
575  Matrix current_transform =
576  Matrix::MakeScale(GetContentScale())
577  .MakeTranslation(
578  Vector3(Point(pass.GetRenderTargetSize().width / 2.0,
579  pass.GetRenderTargetSize().height / 2.0)));
580  Matrix result_transform = current_transform * rotation_matrix;
581  Path path =
582  PathBuilder{}.AddRect(Rect::MakeXYWH(-300, -400, 600, 800)).TakePath();
583 
584  Entity entity;
585  entity.SetTransform(result_transform);
586  entity.SetContents(SolidColorContents::Make(path, Color::Red()));
587  return entity.Render(context, pass);
588  };
589  ASSERT_TRUE(OpenPlaygroundHere(callback));
590 }

References impeller::PathBuilder::AddRect(), impeller::kPi, impeller::SolidColorContents::Make(), 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(), impeller::Entity::SetTransform(), and impeller::PathBuilder::TakePath().

◆ TEST_P() [318/456]

impeller::testing::TEST_P ( EntityTest  ,
CanDrawRect   
)

Definition at line 265 of file entity_unittests.cc.

265  {
266  auto contents = std::make_shared<SolidColorContents>();
267  contents->SetGeometry(Geometry::MakeRect(Rect::MakeXYWH(100, 100, 100, 100)));
268  contents->SetColor(Color::Red());
269 
270  Entity entity;
271  entity.SetTransform(Matrix::MakeScale(GetContentScale()));
272  entity.SetContents(contents);
273 
274  ASSERT_TRUE(OpenPlaygroundHere(std::move(entity)));
275 }

References impeller::Geometry::MakeRect(), impeller::Matrix::MakeScale(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Color::Red(), impeller::Entity::SetContents(), and impeller::Entity::SetTransform().

◆ TEST_P() [319/456]

impeller::testing::TEST_P ( EntityTest  ,
CanDrawRRect   
)

Definition at line 277 of file entity_unittests.cc.

277  {
278  auto contents = std::make_shared<SolidColorContents>();
279  auto path = PathBuilder{}
280  .SetConvexity(Convexity::kConvex)
281  .AddRoundedRect(Rect::MakeXYWH(100, 100, 100, 100), 10.0)
282  .TakePath();
283  contents->SetGeometry(Geometry::MakeFillPath(path));
284  contents->SetColor(Color::Red());
285 
286  Entity entity;
287  entity.SetTransform(Matrix::MakeScale(GetContentScale()));
288  entity.SetContents(contents);
289 
290  ASSERT_TRUE(OpenPlaygroundHere(std::move(entity)));
291 }

References impeller::PathBuilder::AddRoundedRect(), impeller::kConvex, impeller::Geometry::MakeFillPath(), impeller::Matrix::MakeScale(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Color::Red(), impeller::Entity::SetContents(), impeller::PathBuilder::SetConvexity(), impeller::Entity::SetTransform(), and impeller::PathBuilder::TakePath().

◆ TEST_P() [320/456]

impeller::testing::TEST_P ( EntityTest  ,
CanRenderEmptyPathsWithoutCrashing   
)

Definition at line 2571 of file entity_unittests.cc.

2571  {
2572  PathBuilder builder = {};
2573  builder.AddRect(Rect::MakeLTRB(0, 0, 0, 0));
2574  Path path = builder.TakePath();
2575 
2576  EXPECT_TRUE(path.GetBoundingBox()->IsEmpty());
2577 
2578  auto contents = std::make_shared<SolidColorContents>();
2579  contents->SetGeometry(Geometry::MakeFillPath(path));
2580  contents->SetColor(Color::Red());
2581 
2582  Entity entity;
2583  entity.SetTransform(Matrix::MakeScale(GetContentScale()));
2584  entity.SetContents(contents);
2585 
2586  ASSERT_TRUE(OpenPlaygroundHere(std::move(entity)));
2587 }

References impeller::PathBuilder::AddRect(), impeller::Path::GetBoundingBox(), impeller::Geometry::MakeFillPath(), impeller::TRect< Scalar >::MakeLTRB(), impeller::Matrix::MakeScale(), impeller::Color::Red(), impeller::Entity::SetContents(), impeller::Entity::SetTransform(), and impeller::PathBuilder::TakePath().

◆ TEST_P() [321/456]

impeller::testing::TEST_P ( EntityTest  ,
ClipContentsGetClipCoverageIsCorrect   
)

Definition at line 1534 of file entity_unittests.cc.

1534  {
1535  // Intersection: No stencil coverage, no geometry.
1536  {
1537  auto clip = std::make_shared<ClipContents>();
1538  clip->SetClipOperation(Entity::ClipOperation::kIntersect);
1539  auto result = clip->GetClipCoverage(Entity{}, Rect{});
1540 
1541  ASSERT_FALSE(result.coverage.has_value());
1542  }
1543 
1544  // Intersection: No stencil coverage, with geometry.
1545  {
1546  auto clip = std::make_shared<ClipContents>();
1547  clip->SetClipOperation(Entity::ClipOperation::kIntersect);
1548  clip->SetGeometry(Geometry::MakeFillPath(
1549  PathBuilder{}.AddRect(Rect::MakeLTRB(0, 0, 100, 100)).TakePath()));
1550  auto result = clip->GetClipCoverage(Entity{}, Rect{});
1551 
1552  ASSERT_FALSE(result.coverage.has_value());
1553  }
1554 
1555  // Intersection: With stencil coverage, no geometry.
1556  {
1557  auto clip = std::make_shared<ClipContents>();
1558  clip->SetClipOperation(Entity::ClipOperation::kIntersect);
1559  auto result =
1560  clip->GetClipCoverage(Entity{}, Rect::MakeLTRB(0, 0, 100, 100));
1561 
1562  ASSERT_FALSE(result.coverage.has_value());
1563  }
1564 
1565  // Intersection: With stencil coverage, with geometry.
1566  {
1567  auto clip = std::make_shared<ClipContents>();
1568  clip->SetClipOperation(Entity::ClipOperation::kIntersect);
1569  clip->SetGeometry(Geometry::MakeFillPath(
1570  PathBuilder{}.AddRect(Rect::MakeLTRB(0, 0, 50, 50)).TakePath()));
1571  auto result =
1572  clip->GetClipCoverage(Entity{}, Rect::MakeLTRB(0, 0, 100, 100));
1573 
1574  ASSERT_TRUE(result.coverage.has_value());
1575  ASSERT_RECT_NEAR(result.coverage.value(), Rect::MakeLTRB(0, 0, 50, 50));
1576  ASSERT_EQ(result.type, Contents::ClipCoverage::Type::kAppend);
1577  }
1578 
1579  // Difference: With stencil coverage, with geometry.
1580  {
1581  auto clip = std::make_shared<ClipContents>();
1582  clip->SetClipOperation(Entity::ClipOperation::kDifference);
1583  clip->SetGeometry(Geometry::MakeFillPath(
1584  PathBuilder{}.AddRect(Rect::MakeLTRB(0, 0, 50, 50)).TakePath()));
1585  auto result =
1586  clip->GetClipCoverage(Entity{}, Rect::MakeLTRB(0, 0, 100, 100));
1587 
1588  ASSERT_TRUE(result.coverage.has_value());
1589  ASSERT_RECT_NEAR(result.coverage.value(), Rect::MakeLTRB(0, 0, 100, 100));
1590  ASSERT_EQ(result.type, Contents::ClipCoverage::Type::kAppend);
1591  }
1592 }

References impeller::PathBuilder::AddRect(), ASSERT_RECT_NEAR, impeller::Contents::ClipCoverage::kAppend, impeller::Entity::kDifference, impeller::Entity::kIntersect, impeller::Geometry::MakeFillPath(), and impeller::TRect< Scalar >::MakeLTRB().

◆ TEST_P() [322/456]

impeller::testing::TEST_P ( EntityTest  ,
ClipContentsOptimizesFullScreenIntersectClips   
)

Definition at line 23 of file clip_contents_unittests.cc.

23  {
24  // Set up mock environment.
25 
26  auto content_context = GetContentContext();
27  auto buffer = content_context->GetContext()->CreateCommandBuffer();
28  auto render_target =
29  GetContentContext()->GetRenderTargetCache()->CreateOffscreenMSAA(
30  *content_context->GetContext(), {100, 100},
31  /*mip_count=*/1);
32  auto render_pass = buffer->CreateRenderPass(render_target);
33  auto recording_pass = std::make_shared<RecordingRenderPass>(
34  render_pass, GetContext(), render_target);
35 
36  // Set up clip contents.
37 
38  auto contents = std::make_shared<ClipContents>();
39  contents->SetClipOperation(Entity::ClipOperation::kIntersect);
40  contents->SetGeometry(Geometry::MakeCover());
41 
42  Entity entity;
43  entity.SetContents(std::move(contents));
44 
45  // Render the clip contents.
46 
47  ASSERT_TRUE(recording_pass->GetCommands().empty());
48  ASSERT_TRUE(entity.Render(*content_context, *recording_pass));
49  ASSERT_FALSE(recording_pass->GetCommands().empty());
50 }

References impeller::Entity::kIntersect, impeller::Geometry::MakeCover(), impeller::Entity::Render(), and impeller::Entity::SetContents().

◆ TEST_P() [323/456]

impeller::testing::TEST_P ( EntityTest  ,
ClipContentsShouldRenderIsCorrect   
)

Definition at line 1510 of file entity_unittests.cc.

1510  {
1511  // For clip ops, `ShouldRender` should always return true.
1512 
1513  // Clip.
1514  {
1515  auto clip = std::make_shared<ClipContents>();
1516  ASSERT_TRUE(clip->ShouldRender(Entity{}, Rect::MakeSize(Size{100, 100})));
1517  clip->SetGeometry(Geometry::MakeFillPath(
1518  PathBuilder{}.AddRect(Rect::MakeLTRB(0, 0, 100, 100)).TakePath()));
1519  ASSERT_TRUE(clip->ShouldRender(Entity{}, Rect::MakeSize(Size{100, 100})));
1520  ASSERT_TRUE(
1521  clip->ShouldRender(Entity{}, Rect::MakeLTRB(-100, -100, -50, -50)));
1522  }
1523 
1524  // Clip restore.
1525  {
1526  auto restore = std::make_shared<ClipRestoreContents>();
1527  ASSERT_TRUE(
1528  restore->ShouldRender(Entity{}, Rect::MakeSize(Size{100, 100})));
1529  ASSERT_TRUE(
1530  restore->ShouldRender(Entity{}, Rect::MakeLTRB(-100, -100, -50, -50)));
1531  }
1532 }

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

◆ TEST_P() [324/456]

impeller::testing::TEST_P ( EntityTest  ,
ColorFilterContentsWithLargeGeometry   
)

Definition at line 2342 of file entity_unittests.cc.

2342  {
2343  Entity entity;
2344  entity.SetTransform(Matrix::MakeScale(GetContentScale()));
2345  auto src_contents = std::make_shared<SolidColorContents>();
2346  src_contents->SetGeometry(
2347  Geometry::MakeRect(Rect::MakeLTRB(-300, -500, 30000, 50000)));
2348  src_contents->SetColor(Color::Red());
2349 
2350  auto dst_contents = std::make_shared<SolidColorContents>();
2351  dst_contents->SetGeometry(
2352  Geometry::MakeRect(Rect::MakeLTRB(300, 500, 20000, 30000)));
2353  dst_contents->SetColor(Color::Blue());
2354 
2355  auto contents = ColorFilterContents::MakeBlend(
2356  BlendMode::kSourceOver, {FilterInput::Make(dst_contents, false),
2357  FilterInput::Make(src_contents, false)});
2358  entity.SetContents(std::move(contents));
2359  ASSERT_TRUE(OpenPlaygroundHere(std::move(entity)));
2360 }

References impeller::Color::Blue(), impeller::kSourceOver, 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() [325/456]

impeller::testing::TEST_P ( EntityTest  ,
ColorFilterWithForegroundColorAdvancedBlend   
)

Definition at line 2175 of file entity_unittests.cc.

2175  {
2176  auto image = CreateTextureForFixture("boston.jpg");
2177  auto filter = ColorFilterContents::MakeBlend(
2178  BlendMode::kColorBurn, FilterInput::Make({image}), Color::Red());
2179 
2180  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
2181  Entity entity;
2182  entity.SetTransform(Matrix::MakeScale(GetContentScale()) *
2183  Matrix::MakeTranslation({500, 300}) *
2184  Matrix::MakeScale(Vector2{0.5, 0.5}));
2185  entity.SetContents(filter);
2186  return entity.Render(context, pass);
2187  };
2188  ASSERT_TRUE(OpenPlaygroundHere(callback));
2189 }

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

impeller::testing::TEST_P ( EntityTest  ,
ColorFilterWithForegroundColorClearBlend   
)

Definition at line 2191 of file entity_unittests.cc.

2191  {
2192  auto image = CreateTextureForFixture("boston.jpg");
2193  auto filter = ColorFilterContents::MakeBlend(
2194  BlendMode::kClear, FilterInput::Make({image}), Color::Red());
2195 
2196  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
2197  Entity entity;
2198  entity.SetTransform(Matrix::MakeScale(GetContentScale()) *
2199  Matrix::MakeTranslation({500, 300}) *
2200  Matrix::MakeScale(Vector2{0.5, 0.5}));
2201  entity.SetContents(filter);
2202  return entity.Render(context, pass);
2203  };
2204  ASSERT_TRUE(OpenPlaygroundHere(callback));
2205 }

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

impeller::testing::TEST_P ( EntityTest  ,
ColorFilterWithForegroundColorDstBlend   
)

Definition at line 2223 of file entity_unittests.cc.

2223  {
2224  auto image = CreateTextureForFixture("boston.jpg");
2225  auto filter = ColorFilterContents::MakeBlend(
2226  BlendMode::kDestination, FilterInput::Make({image}), Color::Red());
2227 
2228  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
2229  Entity entity;
2230  entity.SetTransform(Matrix::MakeScale(GetContentScale()) *
2231  Matrix::MakeTranslation({500, 300}) *
2232  Matrix::MakeScale(Vector2{0.5, 0.5}));
2233  entity.SetContents(filter);
2234  return entity.Render(context, pass);
2235  };
2236  ASSERT_TRUE(OpenPlaygroundHere(callback));
2237 }

References impeller::kDestination, 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() [328/456]

impeller::testing::TEST_P ( EntityTest  ,
ColorFilterWithForegroundColorSrcBlend   
)

Definition at line 2207 of file entity_unittests.cc.

2207  {
2208  auto image = CreateTextureForFixture("boston.jpg");
2209  auto filter = ColorFilterContents::MakeBlend(
2210  BlendMode::kSource, FilterInput::Make({image}), Color::Red());
2211 
2212  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
2213  Entity entity;
2214  entity.SetTransform(Matrix::MakeScale(GetContentScale()) *
2215  Matrix::MakeTranslation({500, 300}) *
2216  Matrix::MakeScale(Vector2{0.5, 0.5}));
2217  entity.SetContents(filter);
2218  return entity.Render(context, pass);
2219  };
2220  ASSERT_TRUE(OpenPlaygroundHere(callback));
2221 }

References impeller::kSource, 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() [329/456]

impeller::testing::TEST_P ( EntityTest  ,
ColorFilterWithForegroundColorSrcInBlend   
)

Definition at line 2239 of file entity_unittests.cc.

2239  {
2240  auto image = CreateTextureForFixture("boston.jpg");
2241  auto filter = ColorFilterContents::MakeBlend(
2242  BlendMode::kSourceIn, FilterInput::Make({image}), Color::Red());
2243 
2244  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
2245  Entity entity;
2246  entity.SetTransform(Matrix::MakeScale(GetContentScale()) *
2247  Matrix::MakeTranslation({500, 300}) *
2248  Matrix::MakeScale(Vector2{0.5, 0.5}));
2249  entity.SetContents(filter);
2250  return entity.Render(context, pass);
2251  };
2252  ASSERT_TRUE(OpenPlaygroundHere(callback));
2253 }

References impeller::kSourceIn, 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() [330/456]

impeller::testing::TEST_P ( EntityTest  ,
ColorMatrixFilterCoverageIsCorrect   
)

Definition at line 1647 of file entity_unittests.cc.

1647  {
1648  // Set up a simple color background.
1649  auto fill = std::make_shared<SolidColorContents>();
1650  fill->SetGeometry(Geometry::MakeFillPath(
1651  PathBuilder{}.AddRect(Rect::MakeXYWH(0, 0, 300, 400)).TakePath()));
1652  fill->SetColor(Color::Coral());
1653 
1654  // Set the color matrix filter.
1655  ColorMatrix matrix = {
1656  1, 1, 1, 1, 1, //
1657  1, 1, 1, 1, 1, //
1658  1, 1, 1, 1, 1, //
1659  1, 1, 1, 1, 1, //
1660  };
1661 
1662  auto filter =
1663  ColorFilterContents::MakeColorMatrix(FilterInput::Make(fill), matrix);
1664 
1665  Entity e;
1666  e.SetTransform(Matrix());
1667 
1668  // Confirm that the actual filter coverage matches the expected coverage.
1669  auto actual = filter->GetCoverage(e);
1670  auto expected = Rect::MakeXYWH(0, 0, 300, 400);
1671 
1672  ASSERT_TRUE(actual.has_value());
1673  ASSERT_RECT_NEAR(actual.value(), expected);
1674 }

References impeller::PathBuilder::AddRect(), 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() [331/456]

impeller::testing::TEST_P ( EntityTest  ,
ColorMatrixFilterEditable   
)

Definition at line 1676 of file entity_unittests.cc.

1676  {
1677  auto bay_bridge = CreateTextureForFixture("bay_bridge.jpg");
1678  ASSERT_TRUE(bay_bridge);
1679 
1680  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
1681  // UI state.
1682  static ColorMatrix color_matrix = {
1683  1, 0, 0, 0, 0, //
1684  0, 3, 0, 0, 0, //
1685  0, 0, 1, 0, 0, //
1686  0, 0, 0, 1, 0, //
1687  };
1688  static float offset[2] = {500, 400};
1689  static float rotation = 0;
1690  static float scale[2] = {0.65, 0.65};
1691  static float skew[2] = {0, 0};
1692 
1693  // Define the ImGui
1694  ImGui::Begin("Color Matrix", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
1695  {
1696  std::string label = "##1";
1697  for (int i = 0; i < 20; i += 5) {
1698  ImGui::InputScalarN(label.c_str(), ImGuiDataType_Float,
1699  &(color_matrix.array[i]), 5, nullptr, nullptr,
1700  "%.2f", 0);
1701  label[2]++;
1702  }
1703 
1704  ImGui::SliderFloat2("Translation", &offset[0], 0,
1705  pass.GetRenderTargetSize().width);
1706  ImGui::SliderFloat("Rotation", &rotation, 0, kPi * 2);
1707  ImGui::SliderFloat2("Scale", &scale[0], 0, 3);
1708  ImGui::SliderFloat2("Skew", &skew[0], -3, 3);
1709  }
1710  ImGui::End();
1711 
1712  // Set the color matrix filter.
1713  auto filter = ColorFilterContents::MakeColorMatrix(
1714  FilterInput::Make(bay_bridge), color_matrix);
1715 
1716  // Define the entity with the color matrix filter.
1717  Entity entity;
1718  entity.SetTransform(
1719  Matrix::MakeScale(GetContentScale()) *
1720  Matrix::MakeTranslation(Vector3(offset[0], offset[1])) *
1721  Matrix::MakeRotationZ(Radians(rotation)) *
1722  Matrix::MakeScale(Vector2(scale[0], scale[1])) *
1723  Matrix::MakeSkew(skew[0], skew[1]) *
1724  Matrix::MakeTranslation(-Point(bay_bridge->GetSize()) / 2));
1725  entity.SetContents(filter);
1726  entity.Render(context, pass);
1727 
1728  return true;
1729  };
1730 
1731  ASSERT_TRUE(OpenPlaygroundHere(callback));
1732 }

References impeller::ColorMatrix::array, impeller::kPi, impeller::FilterInput::Make(), impeller::ColorFilterContents::MakeColorMatrix(), impeller::Matrix::MakeRotationZ(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeSkew(), impeller::Matrix::MakeTranslation(), offset, impeller::Entity::Render(), scale, impeller::Entity::SetContents(), and impeller::Entity::SetTransform().

◆ TEST_P() [332/456]

impeller::testing::TEST_P ( EntityTest  ,
ConicalGradientContentsIsOpaque   
)

Definition at line 2283 of file entity_unittests.cc.

2283  {
2284  ConicalGradientContents contents;
2285  contents.SetColors({Color::CornflowerBlue()});
2286  ASSERT_FALSE(contents.IsOpaque());
2287  contents.SetColors({Color::CornflowerBlue().WithAlpha(0.5)});
2288  ASSERT_FALSE(contents.IsOpaque());
2289 }

References impeller::Color::CornflowerBlue(), impeller::Contents::IsOpaque(), impeller::ConicalGradientContents::SetColors(), and impeller::Color::WithAlpha().

◆ TEST_P() [333/456]

impeller::testing::TEST_P ( EntityTest  ,
ContentContextOptionsHasReasonableHashFunctions   
)

Definition at line 2459 of file entity_unittests.cc.

2459  {
2460  ContentContextOptions opts;
2461  auto hash_a = ContentContextOptions::Hash{}(opts);
2462 
2463  opts.blend_mode = BlendMode::kColorBurn;
2464  auto hash_b = ContentContextOptions::Hash{}(opts);
2465 
2466  opts.has_depth_stencil_attachments = false;
2467  auto hash_c = ContentContextOptions::Hash{}(opts);
2468 
2469  opts.primitive_type = PrimitiveType::kPoint;
2470  auto hash_d = ContentContextOptions::Hash{}(opts);
2471 
2472  EXPECT_NE(hash_a, hash_b);
2473  EXPECT_NE(hash_b, hash_c);
2474  EXPECT_NE(hash_c, hash_d);
2475 }

References impeller::ContentContextOptions::blend_mode, impeller::ContentContextOptions::has_depth_stencil_attachments, impeller::kColorBurn, impeller::kPoint, and impeller::ContentContextOptions::primitive_type.

◆ TEST_P() [334/456]

impeller::testing::TEST_P ( EntityTest  ,
ContentsGetBoundsForEmptyPathReturnsNullopt   
)

Definition at line 1335 of file entity_unittests.cc.

1335  {
1336  Entity entity;
1337  entity.SetContents(std::make_shared<SolidColorContents>());
1338  ASSERT_FALSE(entity.GetCoverage().has_value());
1339 }

References impeller::Entity::GetCoverage(), and impeller::Entity::SetContents().

◆ TEST_P() [335/456]

impeller::testing::TEST_P ( EntityTest  ,
CoverageForStrokePathWithNegativeValuesInTransform   
)

Definition at line 2255 of file entity_unittests.cc.

2255  {
2256  auto arrow_head = PathBuilder{}
2257  .MoveTo({50, 120})
2258  .LineTo({120, 190})
2259  .LineTo({190, 120})
2260  .TakePath();
2261  auto geometry = Geometry::MakeStrokePath(arrow_head, 15.0, 4.0, Cap::kRound,
2262  Join::kRound);
2263 
2264  auto transform = Matrix::MakeTranslation({300, 300}) *
2265  Matrix::MakeRotationZ(Radians(kPiOver2));
2266  // Note that e[0][0] used to be tested here, but it was -epsilon solely
2267  // due to floating point inaccuracy in the transcendental trig functions.
2268  // e[1][0] is the intended negative value that we care about (-1.0) as it
2269  // comes from the rotation of pi/2.
2270  EXPECT_LT(transform.e[1][0], 0.0f);
2271  auto coverage = geometry->GetCoverage(transform);
2272  ASSERT_RECT_NEAR(coverage.value(), Rect::MakeXYWH(102.5, 342.5, 85, 155));
2273 }

References ASSERT_RECT_NEAR, impeller::kPiOver2, impeller::kRound, impeller::LineTo(), impeller::Matrix::MakeRotationZ(), impeller::Geometry::MakeStrokePath(), impeller::Matrix::MakeTranslation(), impeller::TRect< Scalar >::MakeXYWH(), impeller::PathBuilder::MoveTo(), and transform.

◆ TEST_P() [336/456]

impeller::testing::TEST_P ( EntityTest  ,
CubicCurveAndOverlapTest   
)

Definition at line 592 of file entity_unittests.cc.

592  {
593  // Compare with https://fiddle.skia.org/c/7a05a3e186c65a8dfb732f68020aae06
594  Path path =
595  PathBuilder{}
596  .MoveTo({359.934, 96.6335})
597  .CubicCurveTo({358.189, 96.7055}, {356.436, 96.7908},
598  {354.673, 96.8895})
599  .CubicCurveTo({354.571, 96.8953}, {354.469, 96.9016},
600  {354.367, 96.9075})
601  .CubicCurveTo({352.672, 97.0038}, {350.969, 97.113},
602  {349.259, 97.2355})
603  .CubicCurveTo({349.048, 97.2506}, {348.836, 97.2678},
604  {348.625, 97.2834})
605  .CubicCurveTo({347.019, 97.4014}, {345.407, 97.5299},
606  {343.789, 97.6722})
607  .CubicCurveTo({343.428, 97.704}, {343.065, 97.7402},
608  {342.703, 97.7734})
609  .CubicCurveTo({341.221, 97.9086}, {339.736, 98.0505},
610  {338.246, 98.207})
611  .CubicCurveTo({337.702, 98.2642}, {337.156, 98.3292},
612  {336.612, 98.3894})
613  .CubicCurveTo({335.284, 98.5356}, {333.956, 98.6837},
614  {332.623, 98.8476})
615  .CubicCurveTo({332.495, 98.8635}, {332.366, 98.8818},
616  {332.237, 98.8982})
617  .LineTo({332.237, 102.601})
618  .LineTo({321.778, 102.601})
619  .LineTo({321.778, 100.382})
620  .CubicCurveTo({321.572, 100.413}, {321.367, 100.442},
621  {321.161, 100.476})
622  .CubicCurveTo({319.22, 100.79}, {317.277, 101.123},
623  {315.332, 101.479})
624  .CubicCurveTo({315.322, 101.481}, {315.311, 101.482},
625  {315.301, 101.484})
626  .LineTo({310.017, 105.94})
627  .LineTo({309.779, 105.427})
628  .LineTo({314.403, 101.651})
629  .CubicCurveTo({314.391, 101.653}, {314.379, 101.656},
630  {314.368, 101.658})
631  .CubicCurveTo({312.528, 102.001}, {310.687, 102.366},
632  {308.846, 102.748})
633  .CubicCurveTo({307.85, 102.955}, {306.855, 103.182}, {305.859, 103.4})
634  .CubicCurveTo({305.048, 103.579}, {304.236, 103.75},
635  {303.425, 103.936})
636  .LineTo({299.105, 107.578})
637  .LineTo({298.867, 107.065})
638  .LineTo({302.394, 104.185})
639  .LineTo({302.412, 104.171})
640  .CubicCurveTo({301.388, 104.409}, {300.366, 104.67},
641  {299.344, 104.921})
642  .CubicCurveTo({298.618, 105.1}, {297.89, 105.269}, {297.165, 105.455})
643  .CubicCurveTo({295.262, 105.94}, {293.36, 106.445},
644  {291.462, 106.979})
645  .CubicCurveTo({291.132, 107.072}, {290.802, 107.163},
646  {290.471, 107.257})
647  .CubicCurveTo({289.463, 107.544}, {288.455, 107.839},
648  {287.449, 108.139})
649  .CubicCurveTo({286.476, 108.431}, {285.506, 108.73},
650  {284.536, 109.035})
651  .CubicCurveTo({283.674, 109.304}, {282.812, 109.579},
652  {281.952, 109.859})
653  .CubicCurveTo({281.177, 110.112}, {280.406, 110.377},
654  {279.633, 110.638})
655  .CubicCurveTo({278.458, 111.037}, {277.256, 111.449},
656  {276.803, 111.607})
657  .CubicCurveTo({276.76, 111.622}, {276.716, 111.637},
658  {276.672, 111.653})
659  .CubicCurveTo({275.017, 112.239}, {273.365, 112.836},
660  {271.721, 113.463})
661  .LineTo({271.717, 113.449})
662  .CubicCurveTo({271.496, 113.496}, {271.238, 113.559},
663  {270.963, 113.628})
664  .CubicCurveTo({270.893, 113.645}, {270.822, 113.663},
665  {270.748, 113.682})
666  .CubicCurveTo({270.468, 113.755}, {270.169, 113.834},
667  {269.839, 113.926})
668  .CubicCurveTo({269.789, 113.94}, {269.732, 113.957},
669  {269.681, 113.972})
670  .CubicCurveTo({269.391, 114.053}, {269.081, 114.143},
671  {268.756, 114.239})
672  .CubicCurveTo({268.628, 114.276}, {268.5, 114.314},
673  {268.367, 114.354})
674  .CubicCurveTo({268.172, 114.412}, {267.959, 114.478},
675  {267.752, 114.54})
676  .CubicCurveTo({263.349, 115.964}, {258.058, 117.695},
677  {253.564, 119.252})
678  .CubicCurveTo({253.556, 119.255}, {253.547, 119.258},
679  {253.538, 119.261})
680  .CubicCurveTo({251.844, 119.849}, {250.056, 120.474},
681  {248.189, 121.131})
682  .CubicCurveTo({248, 121.197}, {247.812, 121.264}, {247.621, 121.331})
683  .CubicCurveTo({247.079, 121.522}, {246.531, 121.715},
684  {245.975, 121.912})
685  .CubicCurveTo({245.554, 122.06}, {245.126, 122.212},
686  {244.698, 122.364})
687  .CubicCurveTo({244.071, 122.586}, {243.437, 122.811},
688  {242.794, 123.04})
689  .CubicCurveTo({242.189, 123.255}, {241.58, 123.472},
690  {240.961, 123.693})
691  .CubicCurveTo({240.659, 123.801}, {240.357, 123.909},
692  {240.052, 124.018})
693  .CubicCurveTo({239.12, 124.351}, {238.18, 124.687}, {237.22, 125.032})
694  .LineTo({237.164, 125.003})
695  .CubicCurveTo({236.709, 125.184}, {236.262, 125.358},
696  {235.81, 125.538})
697  .CubicCurveTo({235.413, 125.68}, {234.994, 125.832},
698  {234.592, 125.977})
699  .CubicCurveTo({234.592, 125.977}, {234.591, 125.977},
700  {234.59, 125.977})
701  .CubicCurveTo({222.206, 130.435}, {207.708, 135.753},
702  {192.381, 141.429})
703  .CubicCurveTo({162.77, 151.336}, {122.17, 156.894}, {84.1123, 160})
704  .LineTo({360, 160})
705  .LineTo({360, 119.256})
706  .LineTo({360, 106.332})
707  .LineTo({360, 96.6307})
708  .CubicCurveTo({359.978, 96.6317}, {359.956, 96.6326},
709  {359.934, 96.6335})
710  .Close()
711  .MoveTo({337.336, 124.143})
712  .CubicCurveTo({337.274, 122.359}, {338.903, 121.511},
713  {338.903, 121.511})
714  .CubicCurveTo({338.903, 121.511}, {338.96, 123.303},
715  {337.336, 124.143})
716  .Close()
717  .MoveTo({340.082, 121.849})
718  .CubicCurveTo({340.074, 121.917}, {340.062, 121.992},
719  {340.046, 122.075})
720  .CubicCurveTo({340.039, 122.109}, {340.031, 122.142},
721  {340.023, 122.177})
722  .CubicCurveTo({340.005, 122.26}, {339.98, 122.346},
723  {339.952, 122.437})
724  .CubicCurveTo({339.941, 122.473}, {339.931, 122.507},
725  {339.918, 122.544})
726  .CubicCurveTo({339.873, 122.672}, {339.819, 122.804},
727  {339.75, 122.938})
728  .CubicCurveTo({339.747, 122.944}, {339.743, 122.949},
729  {339.74, 122.955})
730  .CubicCurveTo({339.674, 123.08}, {339.593, 123.205},
731  {339.501, 123.328})
732  .CubicCurveTo({339.473, 123.366}, {339.441, 123.401},
733  {339.41, 123.438})
734  .CubicCurveTo({339.332, 123.534}, {339.243, 123.625},
735  {339.145, 123.714})
736  .CubicCurveTo({339.105, 123.75}, {339.068, 123.786},
737  {339.025, 123.821})
738  .CubicCurveTo({338.881, 123.937}, {338.724, 124.048},
739  {338.539, 124.143})
740  .CubicCurveTo({338.532, 123.959}, {338.554, 123.79},
741  {338.58, 123.626})
742  .CubicCurveTo({338.58, 123.625}, {338.58, 123.625}, {338.58, 123.625})
743  .CubicCurveTo({338.607, 123.455}, {338.65, 123.299},
744  {338.704, 123.151})
745  .CubicCurveTo({338.708, 123.14}, {338.71, 123.127},
746  {338.714, 123.117})
747  .CubicCurveTo({338.769, 122.971}, {338.833, 122.838},
748  {338.905, 122.712})
749  .CubicCurveTo({338.911, 122.702}, {338.916, 122.69200000000001},
750  {338.922, 122.682})
751  .CubicCurveTo({338.996, 122.557}, {339.072, 122.444},
752  {339.155, 122.34})
753  .CubicCurveTo({339.161, 122.333}, {339.166, 122.326},
754  {339.172, 122.319})
755  .CubicCurveTo({339.256, 122.215}, {339.339, 122.12},
756  {339.425, 122.037})
757  .CubicCurveTo({339.428, 122.033}, {339.431, 122.03},
758  {339.435, 122.027})
759  .CubicCurveTo({339.785, 121.687}, {340.106, 121.511},
760  {340.106, 121.511})
761  .CubicCurveTo({340.106, 121.511}, {340.107, 121.645},
762  {340.082, 121.849})
763  .Close()
764  .MoveTo({340.678, 113.245})
765  .CubicCurveTo({340.594, 113.488}, {340.356, 113.655},
766  {340.135, 113.775})
767  .CubicCurveTo({339.817, 113.948}, {339.465, 114.059},
768  {339.115, 114.151})
769  .CubicCurveTo({338.251, 114.379}, {337.34, 114.516},
770  {336.448, 114.516})
771  .CubicCurveTo({335.761, 114.516}, {335.072, 114.527},
772  {334.384, 114.513})
773  .CubicCurveTo({334.125, 114.508}, {333.862, 114.462},
774  {333.605, 114.424})
775  .CubicCurveTo({332.865, 114.318}, {332.096, 114.184},
776  {331.41, 113.883})
777  .CubicCurveTo({330.979, 113.695}, {330.442, 113.34},
778  {330.672, 112.813})
779  .CubicCurveTo({331.135, 111.755}, {333.219, 112.946},
780  {334.526, 113.833})
781  .CubicCurveTo({334.54, 113.816}, {334.554, 113.8}, {334.569, 113.784})
782  .CubicCurveTo({333.38, 112.708}, {331.749, 110.985},
783  {332.76, 110.402})
784  .CubicCurveTo({333.769, 109.82}, {334.713, 111.93},
785  {335.228, 113.395})
786  .CubicCurveTo({334.915, 111.889}, {334.59, 109.636},
787  {335.661, 109.592})
788  .CubicCurveTo({336.733, 109.636}, {336.408, 111.889},
789  {336.07, 113.389})
790  .CubicCurveTo({336.609, 111.93}, {337.553, 109.82},
791  {338.563, 110.402})
792  .CubicCurveTo({339.574, 110.984}, {337.942, 112.708},
793  {336.753, 113.784})
794  .CubicCurveTo({336.768, 113.8}, {336.782, 113.816},
795  {336.796, 113.833})
796  .CubicCurveTo({338.104, 112.946}, {340.187, 111.755},
797  {340.65, 112.813})
798  .CubicCurveTo({340.71, 112.95}, {340.728, 113.102},
799  {340.678, 113.245})
800  .Close()
801  .MoveTo({346.357, 106.771})
802  .CubicCurveTo({346.295, 104.987}, {347.924, 104.139},
803  {347.924, 104.139})
804  .CubicCurveTo({347.924, 104.139}, {347.982, 105.931},
805  {346.357, 106.771})
806  .Close()
807  .MoveTo({347.56, 106.771})
808  .CubicCurveTo({347.498, 104.987}, {349.127, 104.139},
809  {349.127, 104.139})
810  .CubicCurveTo({349.127, 104.139}, {349.185, 105.931},
811  {347.56, 106.771})
812  .Close()
813  .TakePath();
814  Entity entity;
815  entity.SetTransform(Matrix::MakeScale(GetContentScale()));
816  entity.SetContents(SolidColorContents::Make(path, Color::Red()));
817  ASSERT_TRUE(OpenPlaygroundHere(std::move(entity)));
818 }

References impeller::Close(), impeller::LineTo(), impeller::SolidColorContents::Make(), impeller::Matrix::MakeScale(), impeller::PathBuilder::MoveTo(), impeller::Color::Red(), impeller::Entity::SetContents(), and impeller::Entity::SetTransform().

◆ TEST_P() [337/456]

impeller::testing::TEST_P ( EntityTest  ,
CubicCurveTest   
)

Definition at line 524 of file entity_unittests.cc.

524  {
525  // Compare with https://fiddle.skia.org/c/b3625f26122c9de7afe7794fcf25ead3
526  Path path =
527  PathBuilder{}
528  .MoveTo({237.164, 125.003})
529  .CubicCurveTo({236.709, 125.184}, {236.262, 125.358},
530  {235.81, 125.538})
531  .CubicCurveTo({235.413, 125.68}, {234.994, 125.832},
532  {234.592, 125.977})
533  .CubicCurveTo({234.592, 125.977}, {234.591, 125.977},
534  {234.59, 125.977})
535  .CubicCurveTo({222.206, 130.435}, {207.708, 135.753},
536  {192.381, 141.429})
537  .CubicCurveTo({162.77, 151.336}, {122.17, 156.894}, {84.1123, 160})
538  .Close()
539  .TakePath();
540  Entity entity;
541  entity.SetTransform(Matrix::MakeScale(GetContentScale()));
542  entity.SetContents(SolidColorContents::Make(path, Color::Red()));
543  ASSERT_TRUE(OpenPlaygroundHere(std::move(entity)));
544 }

References impeller::Close(), impeller::SolidColorContents::Make(), impeller::Matrix::MakeScale(), impeller::PathBuilder::MoveTo(), impeller::Color::Red(), impeller::Entity::SetContents(), and impeller::Entity::SetTransform().

◆ TEST_P() [338/456]

impeller::testing::TEST_P ( EntityTest  ,
DecalSpecializationAppliedToMorphologyFilter   
)

Definition at line 2443 of file entity_unittests.cc.

2443  {
2444  auto content_context = GetContentContext();
2445  auto default_color_burn = content_context->GetMorphologyFilterPipeline({
2446  .color_attachment_pixel_format = PixelFormat::kR8G8B8A8UNormInt,
2447  });
2448 
2449  auto decal_supported = static_cast<Scalar>(
2450  GetContext()->GetCapabilities()->SupportsDecalSamplerAddressMode());
2451  std::vector<Scalar> expected_constants = {decal_supported};
2452  ASSERT_EQ(default_color_burn->GetDescriptor().GetSpecializationConstants(),
2453  expected_constants);
2454 }

References impeller::kR8G8B8A8UNormInt.

◆ TEST_P() [339/456]

impeller::testing::TEST_P ( EntityTest  ,
DoesNotCullEntitiesByDefault   
)

Definition at line 1496 of file entity_unittests.cc.

1496  {
1497  auto fill = std::make_shared<SolidColorContents>();
1498  fill->SetColor(Color::CornflowerBlue());
1499  fill->SetGeometry(
1500  Geometry::MakeRect(Rect::MakeLTRB(-1000, -1000, -900, -900)));
1501 
1502  Entity entity;
1503  entity.SetContents(fill);
1504 
1505  // Even though the entity is offscreen, this should still render because we do
1506  // not compute the coverage intersection by default.
1507  EXPECT_TRUE(entity.ShouldRender(Rect::MakeLTRB(0, 0, 100, 100)));
1508 }

References impeller::Color::CornflowerBlue(), impeller::TRect< Scalar >::MakeLTRB(), impeller::Geometry::MakeRect(), impeller::Entity::SetContents(), and impeller::Entity::ShouldRender().

◆ TEST_P() [340/456]

impeller::testing::TEST_P ( EntityTest  ,
EntityPassCanMergeSubpassIntoParent   
)

Definition at line 188 of file entity_unittests.cc.

188  {
189  // Both a red and a blue box should appear if the pass merging has worked
190  // correctly.
191 
192  EntityPass pass;
193  auto subpass = CreatePassWithRectPath(Rect::MakeLTRB(0, 0, 100, 100),
194  Rect::MakeLTRB(50, 50, 150, 150),
195  ContentBoundsPromise::kUnknown, true);
196  pass.AddSubpass(std::move(subpass));
197 
198  Entity entity;
199  entity.SetTransform(Matrix::MakeScale(GetContentScale()));
200  auto contents = std::make_unique<SolidColorContents>();
201  contents->SetGeometry(Geometry::MakeRect(Rect::MakeLTRB(100, 100, 200, 200)));
202  contents->SetColor(Color::Blue());
203  entity.SetContents(std::move(contents));
204 
205  pass.AddEntity(std::move(entity));
206 
207  ASSERT_TRUE(OpenPlaygroundHere(pass));
208 }

References impeller::EntityPass::AddEntity(), impeller::EntityPass::AddSubpass(), impeller::Color::Blue(), CreatePassWithRectPath(), impeller::kUnknown, impeller::TRect< Scalar >::MakeLTRB(), impeller::Geometry::MakeRect(), impeller::Matrix::MakeScale(), impeller::Entity::SetContents(), and impeller::Entity::SetTransform().

◆ TEST_P() [341/456]

impeller::testing::TEST_P ( EntityTest  ,
EntityPassCoverageRespectsCoverageLimit   
)

Definition at line 210 of file entity_unittests.cc.

210  {
211  // Rect is drawn entirely in negative area.
212  auto pass = CreatePassWithRectPath(Rect::MakeLTRB(-200, -200, -100, -100),
213  std::nullopt);
214 
215  // Without coverage limit.
216  {
217  auto pass_coverage = pass->GetElementsCoverage(std::nullopt);
218  ASSERT_TRUE(pass_coverage.has_value());
219  ASSERT_RECT_NEAR(pass_coverage.value(),
220  Rect::MakeLTRB(-200, -200, -100, -100));
221  }
222 
223  // With limit that doesn't overlap.
224  {
225  auto pass_coverage =
226  pass->GetElementsCoverage(Rect::MakeLTRB(0, 0, 100, 100));
227  ASSERT_FALSE(pass_coverage.has_value());
228  }
229 
230  // With limit that partially overlaps.
231  {
232  auto pass_coverage =
233  pass->GetElementsCoverage(Rect::MakeLTRB(-150, -150, 0, 0));
234  ASSERT_TRUE(pass_coverage.has_value());
235  ASSERT_RECT_NEAR(pass_coverage.value(),
236  Rect::MakeLTRB(-150, -150, -100, -100));
237  }
238 }

References ASSERT_RECT_NEAR, CreatePassWithRectPath(), and impeller::TRect< Scalar >::MakeLTRB().

◆ TEST_P() [342/456]

impeller::testing::TEST_P ( EntityTest  ,
EntityPassRespectsUntrustedSubpassBoundsLimit   
)

Definition at line 125 of file entity_unittests.cc.

125  {
126  EntityPass pass;
127 
128  auto subpass0 = CreatePassWithRectPath(Rect::MakeLTRB(0, 0, 100, 100),
129  Rect::MakeLTRB(50, 50, 150, 150));
130  auto subpass1 = CreatePassWithRectPath(Rect::MakeLTRB(500, 500, 1000, 1000),
131  Rect::MakeLTRB(800, 800, 900, 900));
132 
133  auto subpass0_coverage =
134  pass.GetSubpassCoverage(*subpass0.get(), std::nullopt);
135  ASSERT_TRUE(subpass0_coverage.has_value());
136  ASSERT_RECT_NEAR(subpass0_coverage.value(), Rect::MakeLTRB(50, 50, 100, 100));
137 
138  auto subpass1_coverage =
139  pass.GetSubpassCoverage(*subpass1.get(), std::nullopt);
140  ASSERT_TRUE(subpass1_coverage.has_value());
141  ASSERT_RECT_NEAR(subpass1_coverage.value(),
142  Rect::MakeLTRB(800, 800, 900, 900));
143 
144  pass.AddSubpass(std::move(subpass0));
145  pass.AddSubpass(std::move(subpass1));
146 
147  auto coverage = pass.GetElementsCoverage(std::nullopt);
148  ASSERT_TRUE(coverage.has_value());
149  ASSERT_RECT_NEAR(coverage.value(), Rect::MakeLTRB(50, 50, 900, 900));
150 }

References impeller::EntityPass::AddSubpass(), ASSERT_RECT_NEAR, CreatePassWithRectPath(), impeller::EntityPass::GetElementsCoverage(), impeller::EntityPass::GetSubpassCoverage(), and impeller::TRect< Scalar >::MakeLTRB().

◆ TEST_P() [343/456]

impeller::testing::TEST_P ( EntityTest  ,
EntityPassTrustsSnugSubpassBoundsLimit   
)

Definition at line 152 of file entity_unittests.cc.

152  {
153  EntityPass pass;
154 
155  auto subpass0 = //
156  CreatePassWithRectPath(Rect::MakeLTRB(10, 10, 90, 90),
157  Rect::MakeLTRB(5, 5, 95, 95),
158  ContentBoundsPromise::kContainsContents);
159  auto subpass1 = //
160  CreatePassWithRectPath(Rect::MakeLTRB(500, 500, 1000, 1000),
161  Rect::MakeLTRB(495, 495, 1005, 1005),
162  ContentBoundsPromise::kContainsContents);
163 
164  auto subpass0_coverage =
165  pass.GetSubpassCoverage(*subpass0.get(), std::nullopt);
166  EXPECT_TRUE(subpass0_coverage.has_value());
167  // Result should be the overridden bounds
168  // (we lied about them being snug, but the property is respected)
169  EXPECT_RECT_NEAR(subpass0_coverage.value(), Rect::MakeLTRB(5, 5, 95, 95));
170 
171  auto subpass1_coverage =
172  pass.GetSubpassCoverage(*subpass1.get(), std::nullopt);
173  EXPECT_TRUE(subpass1_coverage.has_value());
174  // Result should be the overridden bounds
175  // (we lied about them being snug, but the property is respected)
176  EXPECT_RECT_NEAR(subpass1_coverage.value(),
177  Rect::MakeLTRB(495, 495, 1005, 1005));
178 
179  pass.AddSubpass(std::move(subpass0));
180  pass.AddSubpass(std::move(subpass1));
181 
182  auto coverage = pass.GetElementsCoverage(std::nullopt);
183  EXPECT_TRUE(coverage.has_value());
184  // This result should be the union of the overridden bounds
185  EXPECT_RECT_NEAR(coverage.value(), Rect::MakeLTRB(5, 5, 1005, 1005));
186 }

References impeller::EntityPass::AddSubpass(), CreatePassWithRectPath(), EXPECT_RECT_NEAR, impeller::EntityPass::GetElementsCoverage(), impeller::EntityPass::GetSubpassCoverage(), impeller::kContainsContents, and impeller::TRect< Scalar >::MakeLTRB().

◆ TEST_P() [344/456]

impeller::testing::TEST_P ( EntityTest  ,
FailOnValidationError   
)

Definition at line 2535 of file entity_unittests.cc.

2535  {
2536  if (GetParam() != PlaygroundBackend::kVulkan) {
2537  GTEST_SKIP() << "Validation is only fatal on Vulkan backend.";
2538  }
2539  EXPECT_DEATH(
2540  // The easiest way to trigger a validation error is to try to compile
2541  // a shader with an unsupported pixel format.
2542  GetContentContext()->GetBlendColorBurnPipeline({
2543  .color_attachment_pixel_format = PixelFormat::kUnknown,
2544  .has_depth_stencil_attachments = false,
2545  }),
2546  "");
2547 }

References impeller::kUnknown, and impeller::kVulkan.

◆ TEST_P() [345/456]

impeller::testing::TEST_P ( EntityTest  ,
FillPathGeometryGetPositionBufferReturnsExpectedMode   
)

Definition at line 2501 of file entity_unittests.cc.

2501  {
2502  RenderTarget target;
2503  testing::MockRenderPass mock_pass(GetContext(), target);
2504 
2505  auto get_result = [this, &mock_pass](const Path& path) {
2506  auto geometry = Geometry::MakeFillPath(
2507  path, /* inner rect */ Rect::MakeLTRB(0, 0, 100, 100));
2508  return geometry->GetPositionBuffer(*GetContentContext(), {}, mock_pass);
2509  };
2510 
2511  // Convex path
2512  {
2513  GeometryResult result =
2514  get_result(PathBuilder{}
2515  .AddRect(Rect::MakeLTRB(0, 0, 100, 100))
2516  .SetConvexity(Convexity::kConvex)
2517  .TakePath());
2518  EXPECT_EQ(result.mode, GeometryResult::Mode::kNormal);
2519  }
2520 
2521  // Concave path
2522  {
2523  Path path = PathBuilder{}
2524  .MoveTo({0, 0})
2525  .LineTo({100, 0})
2526  .LineTo({100, 100})
2527  .LineTo({50, 50})
2528  .Close()
2529  .TakePath();
2530  GeometryResult result = get_result(path);
2531  EXPECT_EQ(result.mode, GeometryResult::Mode::kNonZero);
2532  }
2533 }

References impeller::PathBuilder::AddRect(), impeller::Close(), impeller::kConvex, impeller::GeometryResult::kNonZero, impeller::GeometryResult::kNormal, impeller::LineTo(), impeller::Geometry::MakeFillPath(), impeller::TRect< Scalar >::MakeLTRB(), impeller::GeometryResult::mode, and impeller::PathBuilder::MoveTo().

◆ TEST_P() [346/456]

impeller::testing::TEST_P ( EntityTest  ,
FilterCoverageRespectsCropRect   
)

Definition at line 240 of file entity_unittests.cc.

240  {
241  auto image = CreateTextureForFixture("boston.jpg");
242  auto filter = ColorFilterContents::MakeBlend(BlendMode::kSoftLight,
243  FilterInput::Make({image}));
244 
245  // Without the crop rect (default behavior).
246  {
247  auto actual = filter->GetCoverage({});
248  auto expected = Rect::MakeSize(image->GetSize());
249 
250  ASSERT_TRUE(actual.has_value());
251  ASSERT_RECT_NEAR(actual.value(), expected);
252  }
253 
254  // With the crop rect.
255  {
256  auto expected = Rect::MakeLTRB(50, 50, 100, 100);
257  filter->SetCoverageHint(expected);
258  auto actual = filter->GetCoverage({});
259 
260  ASSERT_TRUE(actual.has_value());
261  ASSERT_RECT_NEAR(actual.value(), expected);
262  }
263 }

References ASSERT_RECT_NEAR, impeller::kSoftLight, impeller::FilterInput::Make(), impeller::ColorFilterContents::MakeBlend(), impeller::TRect< Scalar >::MakeLTRB(), and impeller::TRect< Scalar >::MakeSize().

◆ TEST_P() [347/456]

impeller::testing::TEST_P ( EntityTest  ,
Filters   
)

Definition at line 1027 of file entity_unittests.cc.

1027  {
1028  auto bridge = CreateTextureForFixture("bay_bridge.jpg");
1029  auto boston = CreateTextureForFixture("boston.jpg");
1030  auto kalimba = CreateTextureForFixture("kalimba.jpg");
1031  ASSERT_TRUE(bridge && boston && kalimba);
1032 
1033  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
1034  auto fi_bridge = FilterInput::Make(bridge);
1035  auto fi_boston = FilterInput::Make(boston);
1036  auto fi_kalimba = FilterInput::Make(kalimba);
1037 
1038  std::shared_ptr<FilterContents> blend0 = ColorFilterContents::MakeBlend(
1039  BlendMode::kModulate, {fi_kalimba, fi_boston});
1040 
1041  auto blend1 = ColorFilterContents::MakeBlend(
1042  BlendMode::kScreen,
1043  {FilterInput::Make(blend0), fi_bridge, fi_bridge, fi_bridge});
1044 
1045  Entity entity;
1046  entity.SetTransform(Matrix::MakeScale(GetContentScale()) *
1047  Matrix::MakeTranslation({500, 300}) *
1048  Matrix::MakeScale(Vector2{0.5, 0.5}));
1049  entity.SetContents(blend1);
1050  return entity.Render(context, pass);
1051  };
1052  ASSERT_TRUE(OpenPlaygroundHere(callback));
1053 }

References impeller::kModulate, impeller::kScreen, impeller::FilterInput::Make(), impeller::ColorFilterContents::MakeBlend(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeTranslation(), and impeller::Entity::SetTransform().

◆ TEST_P() [348/456]

impeller::testing::TEST_P ( EntityTest  ,
GaussianBlurFilter   
)

Definition at line 1055 of file entity_unittests.cc.

1055  {
1056  auto boston =
1057  CreateTextureForFixture("boston.jpg", /*enable_mipmapping=*/true);
1058  ASSERT_TRUE(boston);
1059 
1060  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
1061  const char* input_type_names[] = {"Texture", "Solid Color"};
1062  const char* blur_type_names[] = {"Image blur", "Mask blur"};
1063  const char* pass_variation_names[] = {"New"};
1064  const char* blur_style_names[] = {"Normal", "Solid", "Outer", "Inner"};
1065  const char* tile_mode_names[] = {"Clamp", "Repeat", "Mirror", "Decal"};
1066  const FilterContents::BlurStyle blur_styles[] = {
1067  FilterContents::BlurStyle::kNormal, FilterContents::BlurStyle::kSolid,
1068  FilterContents::BlurStyle::kOuter, FilterContents::BlurStyle::kInner};
1069  const Entity::TileMode tile_modes[] = {
1070  Entity::TileMode::kClamp, Entity::TileMode::kRepeat,
1071  Entity::TileMode::kMirror, Entity::TileMode::kDecal};
1072 
1073  // UI state.
1074  static int selected_input_type = 0;
1075  static Color input_color = Color::Black();
1076  static int selected_blur_type = 0;
1077  static int selected_pass_variation = 0;
1078  static bool combined_sigma = false;
1079  static float blur_amount_coarse[2] = {0, 0};
1080  static float blur_amount_fine[2] = {10, 10};
1081  static int selected_blur_style = 0;
1082  static int selected_tile_mode = 3;
1083  static Color cover_color(1, 0, 0, 0.2);
1084  static Color bounds_color(0, 1, 0, 0.1);
1085  static float offset[2] = {500, 400};
1086  static float rotation = 0;
1087  static float scale[2] = {0.65, 0.65};
1088  static float skew[2] = {0, 0};
1089  static float path_rect[4] = {0, 0,
1090  static_cast<float>(boston->GetSize().width),
1091  static_cast<float>(boston->GetSize().height)};
1092 
1093  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
1094  {
1095  ImGui::Combo("Input type", &selected_input_type, input_type_names,
1096  sizeof(input_type_names) / sizeof(char*));
1097  if (selected_input_type == 0) {
1098  ImGui::SliderFloat("Input opacity", &input_color.alpha, 0, 1);
1099  } else {
1100  ImGui::ColorEdit4("Input color",
1101  reinterpret_cast<float*>(&input_color));
1102  }
1103  ImGui::Combo("Blur type", &selected_blur_type, blur_type_names,
1104  sizeof(blur_type_names) / sizeof(char*));
1105  if (selected_blur_type == 0) {
1106  ImGui::Combo("Pass variation", &selected_pass_variation,
1107  pass_variation_names,
1108  sizeof(pass_variation_names) / sizeof(char*));
1109  }
1110  ImGui::Checkbox("Combined sigma", &combined_sigma);
1111  if (combined_sigma) {
1112  ImGui::SliderFloat("Sigma (coarse)", blur_amount_coarse, 0, 1000);
1113  ImGui::SliderFloat("Sigma (fine)", blur_amount_fine, 0, 10);
1114  blur_amount_coarse[1] = blur_amount_coarse[0];
1115  blur_amount_fine[1] = blur_amount_fine[0];
1116  } else {
1117  ImGui::SliderFloat2("Sigma (coarse)", blur_amount_coarse, 0, 1000);
1118  ImGui::SliderFloat2("Sigma (fine)", blur_amount_fine, 0, 10);
1119  }
1120  ImGui::Combo("Blur style", &selected_blur_style, blur_style_names,
1121  sizeof(blur_style_names) / sizeof(char*));
1122  ImGui::Combo("Tile mode", &selected_tile_mode, tile_mode_names,
1123  sizeof(tile_mode_names) / sizeof(char*));
1124  ImGui::ColorEdit4("Cover color", reinterpret_cast<float*>(&cover_color));
1125  ImGui::ColorEdit4("Bounds color",
1126  reinterpret_cast<float*>(&bounds_color));
1127  ImGui::SliderFloat2("Translation", offset, 0,
1128  pass.GetRenderTargetSize().width);
1129  ImGui::SliderFloat("Rotation", &rotation, 0, kPi * 2);
1130  ImGui::SliderFloat2("Scale", scale, 0, 3);
1131  ImGui::SliderFloat2("Skew", skew, -3, 3);
1132  ImGui::SliderFloat4("Path XYWH", path_rect, -1000, 1000);
1133  }
1134  ImGui::End();
1135 
1136  auto blur_sigma_x = Sigma{blur_amount_coarse[0] + blur_amount_fine[0]};
1137  auto blur_sigma_y = Sigma{blur_amount_coarse[1] + blur_amount_fine[1]};
1138 
1139  std::shared_ptr<Contents> input;
1140  Size input_size;
1141 
1142  auto input_rect =
1143  Rect::MakeXYWH(path_rect[0], path_rect[1], path_rect[2], path_rect[3]);
1144  if (selected_input_type == 0) {
1145  auto texture = std::make_shared<TextureContents>();
1146  texture->SetSourceRect(Rect::MakeSize(boston->GetSize()));
1147  texture->SetDestinationRect(input_rect);
1148  texture->SetTexture(boston);
1149  texture->SetOpacity(input_color.alpha);
1150 
1151  input = texture;
1152  input_size = input_rect.GetSize();
1153  } else {
1154  auto fill = std::make_shared<SolidColorContents>();
1155  fill->SetColor(input_color);
1156  fill->SetGeometry(
1157  Geometry::MakeFillPath(PathBuilder{}.AddRect(input_rect).TakePath()));
1158 
1159  input = fill;
1160  input_size = input_rect.GetSize();
1161  }
1162 
1163  std::shared_ptr<FilterContents> blur;
1164  switch (selected_pass_variation) {
1165  case 0:
1166  blur = std::make_shared<GaussianBlurFilterContents>(
1167  blur_sigma_x.sigma, blur_sigma_y.sigma,
1168  tile_modes[selected_tile_mode], blur_styles[selected_blur_style],
1169  /*geometry=*/nullptr);
1170  blur->SetInputs({FilterInput::Make(input)});
1171  break;
1172  case 1:
1173  blur = FilterContents::MakeGaussianBlur(
1174  FilterInput::Make(input), blur_sigma_x, blur_sigma_y,
1175  tile_modes[selected_tile_mode], blur_styles[selected_blur_style]);
1176  break;
1177  };
1178  FML_CHECK(blur);
1179 
1180  auto mask_blur = FilterContents::MakeBorderMaskBlur(
1181  FilterInput::Make(input), blur_sigma_x, blur_sigma_y,
1182  blur_styles[selected_blur_style]);
1183 
1184  auto ctm = Matrix::MakeScale(GetContentScale()) *
1185  Matrix::MakeTranslation(Vector3(offset[0], offset[1])) *
1186  Matrix::MakeRotationZ(Radians(rotation)) *
1187  Matrix::MakeScale(Vector2(scale[0], scale[1])) *
1188  Matrix::MakeSkew(skew[0], skew[1]) *
1189  Matrix::MakeTranslation(-Point(input_size) / 2);
1190 
1191  auto target_contents = selected_blur_type == 0 ? blur : mask_blur;
1192 
1193  Entity entity;
1194  entity.SetContents(target_contents);
1195  entity.SetTransform(ctm);
1196 
1197  entity.Render(context, pass);
1198 
1199  // Renders a red "cover" rectangle that shows the original position of the
1200  // unfiltered input.
1201  Entity cover_entity;
1202  cover_entity.SetContents(SolidColorContents::Make(
1203  PathBuilder{}.AddRect(input_rect).TakePath(), cover_color));
1204  cover_entity.SetTransform(ctm);
1205 
1206  cover_entity.Render(context, pass);
1207 
1208  // Renders a green bounding rect of the target filter.
1209  Entity bounds_entity;
1210  std::optional<Rect> target_contents_coverage =
1211  target_contents->GetCoverage(entity);
1212  if (target_contents_coverage.has_value()) {
1213  bounds_entity.SetContents(SolidColorContents::Make(
1214  PathBuilder{}
1215  .AddRect(target_contents->GetCoverage(entity).value())
1216  .TakePath(),
1217  bounds_color));
1218  bounds_entity.SetTransform(Matrix());
1219 
1220  bounds_entity.Render(context, pass);
1221  }
1222 
1223  return true;
1224  };
1225  ASSERT_TRUE(OpenPlaygroundHere(callback));
1226 }

References impeller::PathBuilder::AddRect(), 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::SolidColorContents::Make(), 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(), offset, impeller::Entity::Render(), scale, impeller::Entity::SetContents(), impeller::Entity::SetTransform(), and impeller::PathBuilder::TakePath().

◆ TEST_P() [349/456]

impeller::testing::TEST_P ( EntityTest  ,
GeometryBoundsAreTransformed   
)

Definition at line 293 of file entity_unittests.cc.

293  {
294  auto geometry = Geometry::MakeRect(Rect::MakeXYWH(100, 100, 100, 100));
295  auto transform = Matrix::MakeScale({2.0, 2.0, 2.0});
296 
297  ASSERT_RECT_NEAR(geometry->GetCoverage(transform).value(),
298  Rect::MakeXYWH(200, 200, 200, 200));
299 }

References ASSERT_RECT_NEAR, impeller::Geometry::MakeRect(), impeller::Matrix::MakeScale(), impeller::TRect< Scalar >::MakeXYWH(), and transform.

◆ TEST_P() [350/456]

impeller::testing::TEST_P ( EntityTest  ,
InheritOpacityTest   
)

Definition at line 2125 of file entity_unittests.cc.

2125  {
2126  Entity entity;
2127 
2128  // Texture contents can always accept opacity.
2129  auto texture_contents = std::make_shared<TextureContents>();
2130  texture_contents->SetOpacity(0.5);
2131  ASSERT_TRUE(texture_contents->CanInheritOpacity(entity));
2132 
2133  texture_contents->SetInheritedOpacity(0.5);
2134  ASSERT_EQ(texture_contents->GetOpacity(), 0.25);
2135  texture_contents->SetInheritedOpacity(0.5);
2136  ASSERT_EQ(texture_contents->GetOpacity(), 0.25);
2137 
2138  // Solid color contents can accept opacity if their geometry
2139  // doesn't overlap.
2140  auto solid_color = std::make_shared<SolidColorContents>();
2141  solid_color->SetGeometry(
2142  Geometry::MakeRect(Rect::MakeLTRB(100, 100, 200, 200)));
2143  solid_color->SetColor(Color::Blue().WithAlpha(0.5));
2144 
2145  ASSERT_TRUE(solid_color->CanInheritOpacity(entity));
2146 
2147  solid_color->SetInheritedOpacity(0.5);
2148  ASSERT_EQ(solid_color->GetColor().alpha, 0.25);
2149  solid_color->SetInheritedOpacity(0.5);
2150  ASSERT_EQ(solid_color->GetColor().alpha, 0.25);
2151 
2152  // Color source contents can accept opacity if their geometry
2153  // doesn't overlap.
2154  auto tiled_texture = std::make_shared<TiledTextureContents>();
2155  tiled_texture->SetGeometry(
2156  Geometry::MakeRect(Rect::MakeLTRB(100, 100, 200, 200)));
2157  tiled_texture->SetOpacityFactor(0.5);
2158 
2159  ASSERT_TRUE(tiled_texture->CanInheritOpacity(entity));
2160 
2161  tiled_texture->SetInheritedOpacity(0.5);
2162  ASSERT_EQ(tiled_texture->GetOpacityFactor(), 0.25);
2163  tiled_texture->SetInheritedOpacity(0.5);
2164  ASSERT_EQ(tiled_texture->GetOpacityFactor(), 0.25);
2165 
2166  // Clips and restores trivially accept opacity.
2167  ASSERT_TRUE(ClipContents().CanInheritOpacity(entity));
2168  ASSERT_TRUE(ClipRestoreContents().CanInheritOpacity(entity));
2169 
2170  // Runtime effect contents can't accept opacity.
2171  auto runtime_effect = std::make_shared<RuntimeEffectContents>();
2172  ASSERT_FALSE(runtime_effect->CanInheritOpacity(entity));
2173 }

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

◆ TEST_P() [351/456]

impeller::testing::TEST_P ( EntityTest  ,
LinearGradientContentsIsOpaque   
)

Definition at line 2291 of file entity_unittests.cc.

2291  {
2292  LinearGradientContents contents;
2293  contents.SetColors({Color::CornflowerBlue()});
2294  ASSERT_TRUE(contents.IsOpaque());
2295  contents.SetColors({Color::CornflowerBlue().WithAlpha(0.5)});
2296  ASSERT_FALSE(contents.IsOpaque());
2297  contents.SetColors({Color::CornflowerBlue()});
2298  contents.SetTileMode(Entity::TileMode::kDecal);
2299  ASSERT_FALSE(contents.IsOpaque());
2300 }

References impeller::Color::CornflowerBlue(), impeller::LinearGradientContents::IsOpaque(), impeller::Entity::kDecal, impeller::LinearGradientContents::SetColors(), impeller::LinearGradientContents::SetTileMode(), and impeller::Color::WithAlpha().

◆ TEST_P() [352/456]

impeller::testing::TEST_P ( EntityTest  ,
LinearToSrgbFilter   
)

Definition at line 1755 of file entity_unittests.cc.

1755  {
1756  auto image = CreateTextureForFixture("kalimba.jpg");
1757  ASSERT_TRUE(image);
1758 
1759  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
1760  auto filtered =
1761  ColorFilterContents::MakeLinearToSrgbFilter(FilterInput::Make(image));
1762 
1763  // Define the entity that will serve as the control image as a Gaussian blur
1764  // filter with no filter at all.
1765  Entity entity_left;
1766  entity_left.SetTransform(Matrix::MakeScale(GetContentScale()) *
1767  Matrix::MakeTranslation({100, 300}) *
1768  Matrix::MakeScale(Vector2{0.5, 0.5}));
1769  auto unfiltered = FilterContents::MakeGaussianBlur(FilterInput::Make(image),
1770  Sigma{0}, Sigma{0});
1771  entity_left.SetContents(unfiltered);
1772 
1773  // Define the entity that will be filtered from linear to sRGB.
1774  Entity entity_right;
1775  entity_right.SetTransform(Matrix::MakeScale(GetContentScale()) *
1776  Matrix::MakeTranslation({500, 300}) *
1777  Matrix::MakeScale(Vector2{0.5, 0.5}));
1778  entity_right.SetContents(filtered);
1779  return entity_left.Render(context, pass) &&
1780  entity_right.Render(context, pass);
1781  };
1782 
1783  ASSERT_TRUE(OpenPlaygroundHere(callback));
1784 }

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

impeller::testing::TEST_P ( EntityTest  ,
LinearToSrgbFilterCoverageIsCorrect   
)

Definition at line 1734 of file entity_unittests.cc.

1734  {
1735  // Set up a simple color background.
1736  auto fill = std::make_shared<SolidColorContents>();
1737  fill->SetGeometry(Geometry::MakeFillPath(
1738  PathBuilder{}.AddRect(Rect::MakeXYWH(0, 0, 300, 400)).TakePath()));
1739  fill->SetColor(Color::MintCream());
1740 
1741  auto filter =
1742  ColorFilterContents::MakeLinearToSrgbFilter(FilterInput::Make(fill));
1743 
1744  Entity e;
1745  e.SetTransform(Matrix());
1746 
1747  // Confirm that the actual filter coverage matches the expected coverage.
1748  auto actual = filter->GetCoverage(e);
1749  auto expected = Rect::MakeXYWH(0, 0, 300, 400);
1750 
1751  ASSERT_TRUE(actual.has_value());
1752  ASSERT_RECT_NEAR(actual.value(), expected);
1753 }

References impeller::PathBuilder::AddRect(), 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() [354/456]

impeller::testing::TEST_P ( EntityTest  ,
MorphologyFilter   
)

Definition at line 1228 of file entity_unittests.cc.

1228  {
1229  auto boston = CreateTextureForFixture("boston.jpg");
1230  ASSERT_TRUE(boston);
1231 
1232  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
1233  const char* morphology_type_names[] = {"Dilate", "Erode"};
1234  const FilterContents::MorphType morphology_types[] = {
1235  FilterContents::MorphType::kDilate, FilterContents::MorphType::kErode};
1236  static Color input_color = Color::Black();
1237  // UI state.
1238  static int selected_morphology_type = 0;
1239  static float radius[2] = {20, 20};
1240  static Color cover_color(1, 0, 0, 0.2);
1241  static Color bounds_color(0, 1, 0, 0.1);
1242  static float offset[2] = {500, 400};
1243  static float rotation = 0;
1244  static float scale[2] = {0.65, 0.65};
1245  static float skew[2] = {0, 0};
1246  static float path_rect[4] = {0, 0,
1247  static_cast<float>(boston->GetSize().width),
1248  static_cast<float>(boston->GetSize().height)};
1249  static float effect_transform_scale = 1;
1250 
1251  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
1252  {
1253  ImGui::Combo("Morphology type", &selected_morphology_type,
1254  morphology_type_names,
1255  sizeof(morphology_type_names) / sizeof(char*));
1256  ImGui::SliderFloat2("Radius", radius, 0, 200);
1257  ImGui::SliderFloat("Input opacity", &input_color.alpha, 0, 1);
1258  ImGui::ColorEdit4("Cover color", reinterpret_cast<float*>(&cover_color));
1259  ImGui::ColorEdit4("Bounds color",
1260  reinterpret_cast<float*>(&bounds_color));
1261  ImGui::SliderFloat2("Translation", offset, 0,
1262  pass.GetRenderTargetSize().width);
1263  ImGui::SliderFloat("Rotation", &rotation, 0, kPi * 2);
1264  ImGui::SliderFloat2("Scale", scale, 0, 3);
1265  ImGui::SliderFloat2("Skew", skew, -3, 3);
1266  ImGui::SliderFloat4("Path XYWH", path_rect, -1000, 1000);
1267  ImGui::SliderFloat("Effect transform scale", &effect_transform_scale, 0,
1268  3);
1269  }
1270  ImGui::End();
1271 
1272  std::shared_ptr<Contents> input;
1273  Size input_size;
1274 
1275  auto input_rect =
1276  Rect::MakeXYWH(path_rect[0], path_rect[1], path_rect[2], path_rect[3]);
1277  auto texture = std::make_shared<TextureContents>();
1278  texture->SetSourceRect(Rect::MakeSize(boston->GetSize()));
1279  texture->SetDestinationRect(input_rect);
1280  texture->SetTexture(boston);
1281  texture->SetOpacity(input_color.alpha);
1282 
1283  input = texture;
1284  input_size = input_rect.GetSize();
1285 
1286  auto contents = FilterContents::MakeMorphology(
1287  FilterInput::Make(input), Radius{radius[0]}, Radius{radius[1]},
1288  morphology_types[selected_morphology_type]);
1289  contents->SetEffectTransform(Matrix::MakeScale(
1290  Vector2{effect_transform_scale, effect_transform_scale}));
1291 
1292  auto ctm = Matrix::MakeScale(GetContentScale()) *
1293  Matrix::MakeTranslation(Vector3(offset[0], offset[1])) *
1294  Matrix::MakeRotationZ(Radians(rotation)) *
1295  Matrix::MakeScale(Vector2(scale[0], scale[1])) *
1296  Matrix::MakeSkew(skew[0], skew[1]) *
1297  Matrix::MakeTranslation(-Point(input_size) / 2);
1298 
1299  Entity entity;
1300  entity.SetContents(contents);
1301  entity.SetTransform(ctm);
1302 
1303  entity.Render(context, pass);
1304 
1305  // Renders a red "cover" rectangle that shows the original position of the
1306  // unfiltered input.
1307  Entity cover_entity;
1308  cover_entity.SetContents(SolidColorContents::Make(
1309  PathBuilder{}.AddRect(input_rect).TakePath(), cover_color));
1310  cover_entity.SetTransform(ctm);
1311 
1312  cover_entity.Render(context, pass);
1313 
1314  // Renders a green bounding rect of the target filter.
1315  Entity bounds_entity;
1316  bounds_entity.SetContents(SolidColorContents::Make(
1317  PathBuilder{}.AddRect(contents->GetCoverage(entity).value()).TakePath(),
1318  bounds_color));
1319  bounds_entity.SetTransform(Matrix());
1320 
1321  bounds_entity.Render(context, pass);
1322 
1323  return true;
1324  };
1325  ASSERT_TRUE(OpenPlaygroundHere(callback));
1326 }

References impeller::PathBuilder::AddRect(), impeller::Color::alpha, impeller::Color::Black(), impeller::FilterContents::kDilate, impeller::FilterContents::kErode, impeller::kPi, impeller::SolidColorContents::Make(), impeller::FilterInput::Make(), impeller::FilterContents::MakeMorphology(), impeller::Matrix::MakeRotationZ(), impeller::Matrix::MakeScale(), impeller::TRect< Scalar >::MakeSize(), impeller::Matrix::MakeSkew(), impeller::Matrix::MakeTranslation(), impeller::TRect< Scalar >::MakeXYWH(), offset, impeller::Entity::Render(), scale, impeller::Entity::SetContents(), impeller::Entity::SetTransform(), and impeller::PathBuilder::TakePath().

◆ TEST_P() [355/456]

impeller::testing::TEST_P ( EntityTest  ,
PointFieldGeometryCoverage   
)

Definition at line 2334 of file entity_unittests.cc.

2334  {
2335  std::vector<Point> points = {{10, 20}, {100, 200}};
2336  auto geometry = Geometry::MakePointField(points, 5.0, false);
2337  ASSERT_EQ(*geometry->GetCoverage(Matrix()), Rect::MakeLTRB(5, 15, 105, 205));
2338  ASSERT_EQ(*geometry->GetCoverage(Matrix::MakeTranslation({30, 0, 0})),
2339  Rect::MakeLTRB(35, 15, 135, 205));
2340 }

References impeller::TRect< Scalar >::MakeLTRB(), impeller::Geometry::MakePointField(), and impeller::Matrix::MakeTranslation().

◆ TEST_P() [356/456]

impeller::testing::TEST_P ( EntityTest  ,
RadialGradientContentsIsOpaque   
)

Definition at line 2302 of file entity_unittests.cc.

2302  {
2303  RadialGradientContents contents;
2304  contents.SetColors({Color::CornflowerBlue()});
2305  ASSERT_TRUE(contents.IsOpaque());
2306  contents.SetColors({Color::CornflowerBlue().WithAlpha(0.5)});
2307  ASSERT_FALSE(contents.IsOpaque());
2308  contents.SetColors({Color::CornflowerBlue()});
2309  contents.SetTileMode(Entity::TileMode::kDecal);
2310  ASSERT_FALSE(contents.IsOpaque());
2311 }

References impeller::Color::CornflowerBlue(), impeller::RadialGradientContents::IsOpaque(), impeller::Entity::kDecal, impeller::RadialGradientContents::SetColors(), impeller::RadialGradientContents::SetTileMode(), and impeller::Color::WithAlpha().

◆ TEST_P() [357/456]

impeller::testing::TEST_P ( EntityTest  ,
RRectShadowTest   
)

Definition at line 1594 of file entity_unittests.cc.

1594  {
1595  auto callback = [&](ContentContext& context, RenderPass& pass) {
1596  static Color color = Color::Red();
1597  static float corner_radius = 100;
1598  static float blur_radius = 100;
1599  static bool show_coverage = false;
1600  static Color coverage_color = Color::Green().WithAlpha(0.2);
1601 
1602  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
1603  ImGui::SliderFloat("Corner radius", &corner_radius, 0, 300);
1604  ImGui::SliderFloat("Blur radius", &blur_radius, 0, 300);
1605  ImGui::ColorEdit4("Color", reinterpret_cast<Scalar*>(&color));
1606  ImGui::Checkbox("Show coverage", &show_coverage);
1607  if (show_coverage) {
1608  ImGui::ColorEdit4("Coverage color",
1609  reinterpret_cast<Scalar*>(&coverage_color));
1610  }
1611  ImGui::End();
1612 
1613  static PlaygroundPoint top_left_point(Point(200, 200), 30, Color::White());
1614  static PlaygroundPoint bottom_right_point(Point(600, 400), 30,
1615  Color::White());
1616  auto [top_left, bottom_right] =
1617  DrawPlaygroundLine(top_left_point, bottom_right_point);
1618  auto rect =
1619  Rect::MakeLTRB(top_left.x, top_left.y, bottom_right.x, bottom_right.y);
1620 
1621  auto contents = std::make_unique<SolidRRectBlurContents>();
1622  contents->SetRRect(rect, {corner_radius, corner_radius});
1623  contents->SetColor(color);
1624  contents->SetSigma(Radius(blur_radius));
1625 
1626  Entity entity;
1627  entity.SetTransform(Matrix::MakeScale(GetContentScale()));
1628  entity.SetContents(std::move(contents));
1629  entity.Render(context, pass);
1630 
1631  auto coverage = entity.GetCoverage();
1632  if (show_coverage && coverage.has_value()) {
1633  auto bounds_contents = std::make_unique<SolidColorContents>();
1634  bounds_contents->SetGeometry(Geometry::MakeFillPath(
1635  PathBuilder{}.AddRect(entity.GetCoverage().value()).TakePath()));
1636  bounds_contents->SetColor(coverage_color.Premultiply());
1637  Entity bounds_entity;
1638  bounds_entity.SetContents(std::move(bounds_contents));
1639  bounds_entity.Render(context, pass);
1640  }
1641 
1642  return true;
1643  };
1644  ASSERT_TRUE(OpenPlaygroundHere(callback));
1645 }

References impeller::PathBuilder::AddRect(), blur_radius, color, 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::PathBuilder::TakePath(), impeller::Color::White(), and impeller::Color::WithAlpha().

◆ TEST_P() [358/456]

impeller::testing::TEST_P ( EntityTest  ,
RuntimeEffect   
)

Definition at line 1949 of file entity_unittests.cc.

1949  {
1950  auto runtime_stages =
1951  OpenAssetAsRuntimeStage("runtime_stage_example.frag.iplr");
1952  auto runtime_stage =
1953  runtime_stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
1954  ASSERT_TRUE(runtime_stage);
1955  ASSERT_TRUE(runtime_stage->IsDirty());
1956 
1957  bool expect_dirty = true;
1958  Pipeline<PipelineDescriptor>* first_pipeline;
1959  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
1960  EXPECT_EQ(runtime_stage->IsDirty(), expect_dirty);
1961 
1962  auto contents = std::make_shared<RuntimeEffectContents>();
1963  contents->SetGeometry(Geometry::MakeCover());
1964  contents->SetRuntimeStage(runtime_stage);
1965 
1966  struct FragUniforms {
1967  Vector2 iResolution;
1968  Scalar iTime;
1969  } frag_uniforms = {
1970  .iResolution = Vector2(GetWindowSize().width, GetWindowSize().height),
1971  .iTime = static_cast<Scalar>(GetSecondsElapsed()),
1972  };
1973  auto uniform_data = std::make_shared<std::vector<uint8_t>>();
1974  uniform_data->resize(sizeof(FragUniforms));
1975  memcpy(uniform_data->data(), &frag_uniforms, sizeof(FragUniforms));
1976  contents->SetUniformData(uniform_data);
1977 
1978  Entity entity;
1979  entity.SetContents(contents);
1980  bool result = contents->Render(context, entity, pass);
1981 
1982  if (expect_dirty) {
1983  EXPECT_NE(first_pipeline, pass.GetCommands().back().pipeline.get());
1984  first_pipeline = pass.GetCommands().back().pipeline.get();
1985  } else {
1986  EXPECT_EQ(pass.GetCommands().back().pipeline.get(), first_pipeline);
1987  }
1988 
1989  expect_dirty = false;
1990  return result;
1991  };
1992 
1993  // Simulate some renders and hot reloading of the shader.
1994  auto content_context = GetContentContext();
1995  {
1996  RenderTarget target =
1997  content_context->GetRenderTargetCache()->CreateOffscreen(
1998  *content_context->GetContext(), {1, 1}, 1u);
1999 
2000  testing::MockRenderPass mock_pass(GetContext(), target);
2001  callback(*content_context, mock_pass);
2002  callback(*content_context, mock_pass);
2003 
2004  // Dirty the runtime stage.
2005  runtime_stages = OpenAssetAsRuntimeStage("runtime_stage_example.frag.iplr");
2006  runtime_stage =
2007  runtime_stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
2008 
2009  ASSERT_TRUE(runtime_stage->IsDirty());
2010  expect_dirty = true;
2011 
2012  callback(*content_context, mock_pass);
2013  }
2014 }

References impeller::Geometry::MakeCover(), impeller::PlaygroundBackendToRuntimeStageBackend(), and impeller::Entity::SetContents().

◆ TEST_P() [359/456]

impeller::testing::TEST_P ( EntityTest  ,
RuntimeEffectCanPrecache   
)

Definition at line 2063 of file entity_unittests.cc.

2063  {
2064  auto runtime_stages =
2065  OpenAssetAsRuntimeStage("runtime_stage_example.frag.iplr");
2066  auto runtime_stage =
2067  runtime_stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
2068  ASSERT_TRUE(runtime_stage);
2069  ASSERT_TRUE(runtime_stage->IsDirty());
2070 
2071  auto contents = std::make_shared<RuntimeEffectContents>();
2072  contents->SetRuntimeStage(runtime_stage);
2073 
2074  EXPECT_TRUE(contents->BootstrapShader(*GetContentContext()));
2075 }

References impeller::PlaygroundBackendToRuntimeStageBackend().

◆ TEST_P() [360/456]

impeller::testing::TEST_P ( EntityTest  ,
RuntimeEffectCanSuccessfullyRender   
)

Definition at line 2016 of file entity_unittests.cc.

2016  {
2017  auto runtime_stages =
2018  OpenAssetAsRuntimeStage("runtime_stage_example.frag.iplr");
2019  auto runtime_stage =
2020  runtime_stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
2021  ASSERT_TRUE(runtime_stage);
2022  ASSERT_TRUE(runtime_stage->IsDirty());
2023 
2024  auto contents = std::make_shared<RuntimeEffectContents>();
2025  contents->SetGeometry(Geometry::MakeCover());
2026 
2027  contents->SetRuntimeStage(runtime_stage);
2028 
2029  struct FragUniforms {
2030  Vector2 iResolution;
2031  Scalar iTime;
2032  } frag_uniforms = {
2033  .iResolution = Vector2(GetWindowSize().width, GetWindowSize().height),
2034  .iTime = static_cast<Scalar>(GetSecondsElapsed()),
2035  };
2036  auto uniform_data = std::make_shared<std::vector<uint8_t>>();
2037  uniform_data->resize(sizeof(FragUniforms));
2038  memcpy(uniform_data->data(), &frag_uniforms, sizeof(FragUniforms));
2039  contents->SetUniformData(uniform_data);
2040 
2041  Entity entity;
2042  entity.SetContents(contents);
2043 
2044  // Create a render target with a depth-stencil, similar to how EntityPass
2045  // does.
2046  RenderTarget target =
2047  GetContentContext()->GetRenderTargetCache()->CreateOffscreenMSAA(
2048  *GetContext(), {GetWindowSize().width, GetWindowSize().height}, 1,
2049  "RuntimeEffect Texture");
2050  testing::MockRenderPass pass(GetContext(), target);
2051 
2052  ASSERT_TRUE(contents->Render(*GetContentContext(), entity, pass));
2053  ASSERT_EQ(pass.GetCommands().size(), 1u);
2054  const auto& command = pass.GetCommands()[0];
2055  ASSERT_TRUE(command.pipeline->GetDescriptor()
2056  .GetDepthStencilAttachmentDescriptor()
2057  .has_value());
2058  ASSERT_TRUE(command.pipeline->GetDescriptor()
2059  .GetFrontStencilAttachmentDescriptor()
2060  .has_value());
2061 }

References impeller::Geometry::MakeCover(), impeller::PlaygroundBackendToRuntimeStageBackend(), and impeller::Entity::SetContents().

◆ TEST_P() [361/456]

impeller::testing::TEST_P ( EntityTest  ,
RuntimeEffectSetsRightSizeWhenUniformIsStruct   
)

Definition at line 2077 of file entity_unittests.cc.

2077  {
2078  if (GetBackend() != PlaygroundBackend::kVulkan) {
2079  GTEST_SKIP() << "Test only applies to Vulkan";
2080  }
2081 
2082  auto runtime_stages =
2083  OpenAssetAsRuntimeStage("runtime_stage_example.frag.iplr");
2084  auto runtime_stage =
2085  runtime_stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
2086  ASSERT_TRUE(runtime_stage);
2087  ASSERT_TRUE(runtime_stage->IsDirty());
2088 
2089  auto contents = std::make_shared<RuntimeEffectContents>();
2090  contents->SetGeometry(Geometry::MakeCover());
2091  contents->SetRuntimeStage(runtime_stage);
2092 
2093  struct FragUniforms {
2094  Vector2 iResolution;
2095  Scalar iTime;
2096  } frag_uniforms = {
2097  .iResolution = Vector2(GetWindowSize().width, GetWindowSize().height),
2098  .iTime = static_cast<Scalar>(GetSecondsElapsed()),
2099  };
2100  auto uniform_data = std::make_shared<std::vector<uint8_t>>();
2101  uniform_data->resize(sizeof(FragUniforms));
2102  memcpy(uniform_data->data(), &frag_uniforms, sizeof(FragUniforms));
2103  contents->SetUniformData(uniform_data);
2104 
2105  Entity entity;
2106  entity.SetContents(contents);
2107 
2108  auto context = GetContentContext();
2109  RenderTarget target = context->GetRenderTargetCache()->CreateOffscreen(
2110  *context->GetContext(), {1, 1}, 1u);
2111 
2112  testing::MockRenderPass pass(GetContext(), target);
2113  ASSERT_TRUE(contents->Render(*context, entity, pass));
2114  ASSERT_EQ(pass.GetCommands().size(), 1u);
2115  const auto& command = pass.GetCommands()[0];
2116  ASSERT_EQ(command.fragment_bindings.buffers.size(), 1u);
2117  // 16 bytes:
2118  // 8 bytes for iResolution
2119  // 4 bytes for iTime
2120  // 4 bytes padding
2121  EXPECT_EQ(command.fragment_bindings.buffers[0].view.resource.range.length,
2122  16u);
2123 }

References impeller::kVulkan, impeller::Geometry::MakeCover(), impeller::PlaygroundBackendToRuntimeStageBackend(), and impeller::Entity::SetContents().

◆ TEST_P() [362/456]

impeller::testing::TEST_P ( EntityTest  ,
SetBlendMode   
)

Definition at line 1328 of file entity_unittests.cc.

1328  {
1329  Entity entity;
1330  ASSERT_EQ(entity.GetBlendMode(), BlendMode::kSourceOver);
1331  entity.SetBlendMode(BlendMode::kClear);
1332  ASSERT_EQ(entity.GetBlendMode(), BlendMode::kClear);
1333 }

References impeller::Entity::GetBlendMode(), impeller::kClear, impeller::kSourceOver, and impeller::Entity::SetBlendMode().

◆ TEST_P() [363/456]

impeller::testing::TEST_P ( EntityTest  ,
SolidColorContentsIsOpaque   
)

Definition at line 2275 of file entity_unittests.cc.

2275  {
2276  SolidColorContents contents;
2277  contents.SetColor(Color::CornflowerBlue());
2278  ASSERT_TRUE(contents.IsOpaque());
2279  contents.SetColor(Color::CornflowerBlue().WithAlpha(0.5));
2280  ASSERT_FALSE(contents.IsOpaque());
2281 }

References impeller::Color::CornflowerBlue(), impeller::SolidColorContents::IsOpaque(), and impeller::SolidColorContents::SetColor().

◆ TEST_P() [364/456]

impeller::testing::TEST_P ( EntityTest  ,
SolidColorContentsStrokeSetMiterLimit   
)

Definition at line 842 of file entity_unittests.cc.

842  {
843  {
844  auto geometry = Geometry::MakeStrokePath(Path{});
845  auto path_geometry = static_cast<StrokePathGeometry*>(geometry.get());
846  ASSERT_FLOAT_EQ(path_geometry->GetMiterLimit(), 4);
847  }
848 
849  {
850  auto geometry = Geometry::MakeStrokePath(Path{}, 1.0, /*miter_limit=*/8.0);
851  auto path_geometry = static_cast<StrokePathGeometry*>(geometry.get());
852  ASSERT_FLOAT_EQ(path_geometry->GetMiterLimit(), 8);
853  }
854 
855  {
856  auto geometry = Geometry::MakeStrokePath(Path{}, 1.0, /*miter_limit=*/-1.0);
857  auto path_geometry = static_cast<StrokePathGeometry*>(geometry.get());
858  ASSERT_FLOAT_EQ(path_geometry->GetMiterLimit(), 4);
859  }
860 }

References impeller::Geometry::MakeStrokePath().

◆ TEST_P() [365/456]

impeller::testing::TEST_P ( EntityTest  ,
SolidColorContentsStrokeSetStrokeCapsAndJoins   
)

Definition at line 820 of file entity_unittests.cc.

820  {
821  {
822  auto geometry = Geometry::MakeStrokePath(Path{});
823  auto path_geometry = static_cast<StrokePathGeometry*>(geometry.get());
824  // Defaults.
825  ASSERT_EQ(path_geometry->GetStrokeCap(), Cap::kButt);
826  ASSERT_EQ(path_geometry->GetStrokeJoin(), Join::kMiter);
827  }
828 
829  {
830  auto geometry = Geometry::MakeStrokePath(Path{}, 1.0, 4.0, Cap::kSquare);
831  auto path_geometry = static_cast<StrokePathGeometry*>(geometry.get());
832  ASSERT_EQ(path_geometry->GetStrokeCap(), Cap::kSquare);
833  }
834 
835  {
836  auto geometry = Geometry::MakeStrokePath(Path{}, 1.0, 4.0, Cap::kRound);
837  auto path_geometry = static_cast<StrokePathGeometry*>(geometry.get());
838  ASSERT_EQ(path_geometry->GetStrokeCap(), Cap::kRound);
839  }
840 }

References impeller::kButt, impeller::kMiter, impeller::kRound, impeller::kSquare, and impeller::Geometry::MakeStrokePath().

◆ TEST_P() [366/456]

impeller::testing::TEST_P ( EntityTest  ,
SolidFillCoverageIsCorrect   
)

Definition at line 1421 of file entity_unittests.cc.

1421  {
1422  // No transform
1423  {
1424  auto fill = std::make_shared<SolidColorContents>();
1425  fill->SetColor(Color::CornflowerBlue());
1426  auto expected = Rect::MakeLTRB(100, 110, 200, 220);
1427  fill->SetGeometry(
1428  Geometry::MakeFillPath(PathBuilder{}.AddRect(expected).TakePath()));
1429 
1430  auto coverage = fill->GetCoverage({});
1431  ASSERT_TRUE(coverage.has_value());
1432  ASSERT_RECT_NEAR(coverage.value(), expected);
1433  }
1434 
1435  // Entity transform
1436  {
1437  auto fill = std::make_shared<SolidColorContents>();
1438  fill->SetColor(Color::CornflowerBlue());
1439  fill->SetGeometry(Geometry::MakeFillPath(
1440  PathBuilder{}.AddRect(Rect::MakeLTRB(100, 110, 200, 220)).TakePath()));
1441 
1442  Entity entity;
1443  entity.SetTransform(Matrix::MakeTranslation(Vector2(4, 5)));
1444  entity.SetContents(std::move(fill));
1445 
1446  auto coverage = entity.GetCoverage();
1447  auto expected = Rect::MakeLTRB(104, 115, 204, 225);
1448  ASSERT_TRUE(coverage.has_value());
1449  ASSERT_RECT_NEAR(coverage.value(), expected);
1450  }
1451 
1452  // No coverage for fully transparent colors
1453  {
1454  auto fill = std::make_shared<SolidColorContents>();
1455  fill->SetColor(Color::WhiteTransparent());
1456  fill->SetGeometry(Geometry::MakeFillPath(
1457  PathBuilder{}.AddRect(Rect::MakeLTRB(100, 110, 200, 220)).TakePath()));
1458 
1459  auto coverage = fill->GetCoverage({});
1460  ASSERT_FALSE(coverage.has_value());
1461  }
1462 }

References impeller::PathBuilder::AddRect(), 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() [367/456]

impeller::testing::TEST_P ( EntityTest  ,
SolidFillShouldRenderIsCorrect   
)

Definition at line 1464 of file entity_unittests.cc.

1464  {
1465  // No path.
1466  {
1467  auto fill = std::make_shared<SolidColorContents>();
1468  fill->SetColor(Color::CornflowerBlue());
1469  ASSERT_FALSE(fill->ShouldRender(Entity{}, Rect::MakeSize(Size{100, 100})));
1470  ASSERT_FALSE(
1471  fill->ShouldRender(Entity{}, Rect::MakeLTRB(-100, -100, -50, -50)));
1472  }
1473 
1474  // With path.
1475  {
1476  auto fill = std::make_shared<SolidColorContents>();
1477  fill->SetColor(Color::CornflowerBlue());
1478  fill->SetGeometry(Geometry::MakeFillPath(
1479  PathBuilder{}.AddRect(Rect::MakeLTRB(0, 0, 100, 100)).TakePath()));
1480  ASSERT_TRUE(fill->ShouldRender(Entity{}, Rect::MakeSize(Size{100, 100})));
1481  ASSERT_FALSE(
1482  fill->ShouldRender(Entity{}, Rect::MakeLTRB(-100, -100, -50, -50)));
1483  }
1484 
1485  // With paint cover.
1486  {
1487  auto fill = std::make_shared<SolidColorContents>();
1488  fill->SetColor(Color::CornflowerBlue());
1489  fill->SetGeometry(Geometry::MakeCover());
1490  ASSERT_TRUE(fill->ShouldRender(Entity{}, Rect::MakeSize(Size{100, 100})));
1491  ASSERT_TRUE(
1492  fill->ShouldRender(Entity{}, Rect::MakeLTRB(-100, -100, -50, -50)));
1493  }
1494 }

References impeller::PathBuilder::AddRect(), impeller::Color::CornflowerBlue(), impeller::Geometry::MakeCover(), impeller::Geometry::MakeFillPath(), impeller::TRect< Scalar >::MakeLTRB(), and impeller::TRect< Scalar >::MakeSize().

◆ TEST_P() [368/456]

impeller::testing::TEST_P ( EntityTest  ,
SolidStrokeCoverageIsCorrect   
)

Definition at line 1341 of file entity_unittests.cc.

1341  {
1342  {
1343  auto geometry = Geometry::MakeStrokePath(
1344  PathBuilder{}.AddLine({0, 0}, {10, 10}).TakePath(), 4.0, 4.0,
1345  Cap::kButt, Join::kBevel);
1346 
1347  Entity entity;
1348  auto contents = std::make_unique<SolidColorContents>();
1349  contents->SetGeometry(std::move(geometry));
1350  contents->SetColor(Color::Black());
1351  entity.SetContents(std::move(contents));
1352  auto actual = entity.GetCoverage();
1353  auto expected = Rect::MakeLTRB(-2, -2, 12, 12);
1354  ASSERT_TRUE(actual.has_value());
1355  ASSERT_RECT_NEAR(actual.value(), expected);
1356  }
1357 
1358  // Cover the Cap::kSquare case.
1359  {
1360  auto geometry = Geometry::MakeStrokePath(
1361  PathBuilder{}.AddLine({0, 0}, {10, 10}).TakePath(), 4.0, 4.0,
1362  Cap::kSquare, Join::kBevel);
1363 
1364  Entity entity;
1365  auto contents = std::make_unique<SolidColorContents>();
1366  contents->SetGeometry(std::move(geometry));
1367  contents->SetColor(Color::Black());
1368  entity.SetContents(std::move(contents));
1369  auto actual = entity.GetCoverage();
1370  auto expected =
1371  Rect::MakeLTRB(-sqrt(8), -sqrt(8), 10 + sqrt(8), 10 + sqrt(8));
1372  ASSERT_TRUE(actual.has_value());
1373  ASSERT_RECT_NEAR(actual.value(), expected);
1374  }
1375 
1376  // Cover the Join::kMiter case.
1377  {
1378  auto geometry = Geometry::MakeStrokePath(
1379  PathBuilder{}.AddLine({0, 0}, {10, 10}).TakePath(), 4.0, 2.0,
1380  Cap::kSquare, Join::kMiter);
1381 
1382  Entity entity;
1383  auto contents = std::make_unique<SolidColorContents>();
1384  contents->SetGeometry(std::move(geometry));
1385  contents->SetColor(Color::Black());
1386  entity.SetContents(std::move(contents));
1387  auto actual = entity.GetCoverage();
1388  auto expected = Rect::MakeLTRB(-4, -4, 14, 14);
1389  ASSERT_TRUE(actual.has_value());
1390  ASSERT_RECT_NEAR(actual.value(), expected);
1391  }
1392 }

References impeller::PathBuilder::AddLine(), ASSERT_RECT_NEAR, impeller::Color::Black(), impeller::Entity::GetCoverage(), impeller::kBevel, impeller::kButt, impeller::kMiter, impeller::kSquare, impeller::TRect< Scalar >::MakeLTRB(), impeller::Geometry::MakeStrokePath(), and impeller::Entity::SetContents().

◆ TEST_P() [369/456]

impeller::testing::TEST_P ( EntityTest  ,
SpecializationConstantsAreAppliedToVariants   
)

Definition at line 2420 of file entity_unittests.cc.

2420  {
2421  auto content_context = GetContentContext();
2422 
2423  auto default_gyph = content_context->GetGlyphAtlasPipeline({
2424  .color_attachment_pixel_format = PixelFormat::kR8G8B8A8UNormInt,
2425  .has_depth_stencil_attachments = false,
2426  });
2427  auto alt_gyph = content_context->GetGlyphAtlasPipeline(
2428  {.color_attachment_pixel_format = PixelFormat::kR8G8B8A8UNormInt,
2429  .has_depth_stencil_attachments = true});
2430 
2431  EXPECT_NE(default_gyph, alt_gyph);
2432  EXPECT_EQ(default_gyph->GetDescriptor().GetSpecializationConstants(),
2433  alt_gyph->GetDescriptor().GetSpecializationConstants());
2434 
2435  auto use_a8 = GetContext()->GetCapabilities()->GetDefaultGlyphAtlasFormat() ==
2436  PixelFormat::kA8UNormInt;
2437 
2438  std::vector<Scalar> expected_constants = {static_cast<Scalar>(use_a8)};
2439  EXPECT_EQ(default_gyph->GetDescriptor().GetSpecializationConstants(),
2440  expected_constants);
2441 }

References impeller::kA8UNormInt, and impeller::kR8G8B8A8UNormInt.

◆ TEST_P() [370/456]

impeller::testing::TEST_P ( EntityTest  ,
SrgbToLinearFilter   
)

Definition at line 1807 of file entity_unittests.cc.

1807  {
1808  auto image = CreateTextureForFixture("embarcadero.jpg");
1809  ASSERT_TRUE(image);
1810 
1811  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
1812  auto filtered =
1813  ColorFilterContents::MakeSrgbToLinearFilter(FilterInput::Make(image));
1814 
1815  // Define the entity that will serve as the control image as a Gaussian blur
1816  // filter with no filter at all.
1817  Entity entity_left;
1818  entity_left.SetTransform(Matrix::MakeScale(GetContentScale()) *
1819  Matrix::MakeTranslation({100, 300}) *
1820  Matrix::MakeScale(Vector2{0.5, 0.5}));
1821  auto unfiltered = FilterContents::MakeGaussianBlur(FilterInput::Make(image),
1822  Sigma{0}, Sigma{0});
1823  entity_left.SetContents(unfiltered);
1824 
1825  // Define the entity that will be filtered from sRGB to linear.
1826  Entity entity_right;
1827  entity_right.SetTransform(Matrix::MakeScale(GetContentScale()) *
1828  Matrix::MakeTranslation({500, 300}) *
1829  Matrix::MakeScale(Vector2{0.5, 0.5}));
1830  entity_right.SetContents(filtered);
1831  return entity_left.Render(context, pass) &&
1832  entity_right.Render(context, pass);
1833  };
1834 
1835  ASSERT_TRUE(OpenPlaygroundHere(callback));
1836 }

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

impeller::testing::TEST_P ( EntityTest  ,
SrgbToLinearFilterCoverageIsCorrect   
)

Definition at line 1786 of file entity_unittests.cc.

1786  {
1787  // Set up a simple color background.
1788  auto fill = std::make_shared<SolidColorContents>();
1789  fill->SetGeometry(Geometry::MakeFillPath(
1790  PathBuilder{}.AddRect(Rect::MakeXYWH(0, 0, 300, 400)).TakePath()));
1791  fill->SetColor(Color::DeepPink());
1792 
1793  auto filter =
1794  ColorFilterContents::MakeSrgbToLinearFilter(FilterInput::Make(fill));
1795 
1796  Entity e;
1797  e.SetTransform(Matrix());
1798 
1799  // Confirm that the actual filter coverage matches the expected coverage.
1800  auto actual = filter->GetCoverage(e);
1801  auto expected = Rect::MakeXYWH(0, 0, 300, 400);
1802 
1803  ASSERT_TRUE(actual.has_value());
1804  ASSERT_RECT_NEAR(actual.value(), expected);
1805 }

References impeller::PathBuilder::AddRect(), 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() [372/456]

impeller::testing::TEST_P ( EntityTest  ,
StrokeCapAndJoinTest   
)

Definition at line 384 of file entity_unittests.cc.

384  {
385  const Point padding(300, 250);
386  const Point margin(140, 180);
387 
388  auto callback = [&](ContentContext& context, RenderPass& pass) {
389  // Slightly above sqrt(2) by default, so that right angles are just below
390  // the limit and acute angles are over the limit (causing them to get
391  // beveled).
392  static Scalar miter_limit = 1.41421357;
393  static Scalar width = 30;
394 
395  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
396  {
397  ImGui::SliderFloat("Miter limit", &miter_limit, 0, 30);
398  ImGui::SliderFloat("Stroke width", &width, 0, 100);
399  if (ImGui::Button("Reset")) {
400  miter_limit = 1.41421357;
401  width = 30;
402  }
403  }
404  ImGui::End();
405 
406  auto world_matrix = Matrix::MakeScale(GetContentScale());
407  auto render_path = [width = width, &context, &pass, &world_matrix](
408  const Path& path, Cap cap, Join join) {
409  auto contents = std::make_unique<SolidColorContents>();
410  contents->SetGeometry(
411  Geometry::MakeStrokePath(path, width, miter_limit, cap, join));
412  contents->SetColor(Color::Red());
413 
414  Entity entity;
415  entity.SetTransform(world_matrix);
416  entity.SetContents(std::move(contents));
417 
418  auto coverage = entity.GetCoverage();
419  if (coverage.has_value()) {
420  auto bounds_contents = std::make_unique<SolidColorContents>();
421  bounds_contents->SetGeometry(Geometry::MakeFillPath(
422  PathBuilder{}.AddRect(entity.GetCoverage().value()).TakePath()));
423  bounds_contents->SetColor(Color::Green().WithAlpha(0.5));
424  Entity bounds_entity;
425  bounds_entity.SetContents(std::move(bounds_contents));
426  bounds_entity.Render(context, pass);
427  }
428 
429  entity.Render(context, pass);
430  };
431 
432  const Point a_def(0, 0), b_def(0, 100), c_def(150, 0), d_def(150, -100),
433  e_def(75, 75);
434  const Scalar r = 30;
435  // Cap::kButt demo.
436  {
437  Point off = Point(0, 0) * padding + margin;
438  static PlaygroundPoint point_a(off + a_def, r, Color::Black());
439  static PlaygroundPoint point_b(off + b_def, r, Color::White());
440  auto [a, b] = DrawPlaygroundLine(point_a, point_b);
441  static PlaygroundPoint point_c(off + c_def, r, Color::Black());
442  static PlaygroundPoint point_d(off + d_def, r, Color::White());
443  auto [c, d] = DrawPlaygroundLine(point_c, point_d);
444  render_path(PathBuilder{}.AddCubicCurve(a, b, d, c).TakePath(),
445  Cap::kButt, Join::kBevel);
446  }
447 
448  // Cap::kSquare demo.
449  {
450  Point off = Point(1, 0) * padding + margin;
451  static PlaygroundPoint point_a(off + a_def, r, Color::Black());
452  static PlaygroundPoint point_b(off + b_def, r, Color::White());
453  auto [a, b] = DrawPlaygroundLine(point_a, point_b);
454  static PlaygroundPoint point_c(off + c_def, r, Color::Black());
455  static PlaygroundPoint point_d(off + d_def, r, Color::White());
456  auto [c, d] = DrawPlaygroundLine(point_c, point_d);
457  render_path(PathBuilder{}.AddCubicCurve(a, b, d, c).TakePath(),
458  Cap::kSquare, Join::kBevel);
459  }
460 
461  // Cap::kRound demo.
462  {
463  Point off = Point(2, 0) * padding + margin;
464  static PlaygroundPoint point_a(off + a_def, r, Color::Black());
465  static PlaygroundPoint point_b(off + b_def, r, Color::White());
466  auto [a, b] = DrawPlaygroundLine(point_a, point_b);
467  static PlaygroundPoint point_c(off + c_def, r, Color::Black());
468  static PlaygroundPoint point_d(off + d_def, r, Color::White());
469  auto [c, d] = DrawPlaygroundLine(point_c, point_d);
470  render_path(PathBuilder{}.AddCubicCurve(a, b, d, c).TakePath(),
471  Cap::kRound, Join::kBevel);
472  }
473 
474  // Join::kBevel demo.
475  {
476  Point off = Point(0, 1) * padding + margin;
477  static PlaygroundPoint point_a =
478  PlaygroundPoint(off + a_def, r, Color::White());
479  static PlaygroundPoint point_b =
480  PlaygroundPoint(off + e_def, r, Color::White());
481  static PlaygroundPoint point_c =
482  PlaygroundPoint(off + c_def, r, Color::White());
483  Point a = DrawPlaygroundPoint(point_a);
484  Point b = DrawPlaygroundPoint(point_b);
485  Point c = DrawPlaygroundPoint(point_c);
486  render_path(
487  PathBuilder{}.MoveTo(a).LineTo(b).LineTo(c).Close().TakePath(),
488  Cap::kButt, Join::kBevel);
489  }
490 
491  // Join::kMiter demo.
492  {
493  Point off = Point(1, 1) * padding + margin;
494  static PlaygroundPoint point_a(off + a_def, r, Color::White());
495  static PlaygroundPoint point_b(off + e_def, r, Color::White());
496  static PlaygroundPoint point_c(off + c_def, r, Color::White());
497  Point a = DrawPlaygroundPoint(point_a);
498  Point b = DrawPlaygroundPoint(point_b);
499  Point c = DrawPlaygroundPoint(point_c);
500  render_path(
501  PathBuilder{}.MoveTo(a).LineTo(b).LineTo(c).Close().TakePath(),
502  Cap::kButt, Join::kMiter);
503  }
504 
505  // Join::kRound demo.
506  {
507  Point off = Point(2, 1) * padding + margin;
508  static PlaygroundPoint point_a(off + a_def, r, Color::White());
509  static PlaygroundPoint point_b(off + e_def, r, Color::White());
510  static PlaygroundPoint point_c(off + c_def, r, Color::White());
511  Point a = DrawPlaygroundPoint(point_a);
512  Point b = DrawPlaygroundPoint(point_b);
513  Point c = DrawPlaygroundPoint(point_c);
514  render_path(
515  PathBuilder{}.MoveTo(a).LineTo(b).LineTo(c).Close().TakePath(),
516  Cap::kButt, Join::kRound);
517  }
518 
519  return true;
520  };
521  ASSERT_TRUE(OpenPlaygroundHere(callback));
522 }

References impeller::PathBuilder::AddCubicCurve(), impeller::PathBuilder::AddRect(), 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(), impeller::PathBuilder::MoveTo(), padding, impeller::Color::Red(), impeller::Entity::Render(), impeller::Entity::SetContents(), impeller::Entity::SetTransform(), impeller::PathBuilder::TakePath(), and impeller::Color::White().

◆ TEST_P() [373/456]

impeller::testing::TEST_P ( EntityTest  ,
StrokeWithTextureContents   
)

Definition at line 320 of file entity_unittests.cc.

320  {
321  auto bridge = CreateTextureForFixture("bay_bridge.jpg");
322  Path path = PathBuilder{}
323  .MoveTo({100, 100})
324  .LineTo({100, 200})
325  .MoveTo({100, 300})
326  .LineTo({100, 400})
327  .MoveTo({100, 500})
328  .LineTo({100, 600})
329  .TakePath();
330 
331  Entity entity;
332  entity.SetTransform(Matrix::MakeScale(GetContentScale()));
333  auto contents = std::make_unique<TiledTextureContents>();
334  contents->SetGeometry(Geometry::MakeStrokePath(path, 100.0));
335  contents->SetTexture(bridge);
336  contents->SetTileModes(Entity::TileMode::kClamp, Entity::TileMode::kClamp);
337  entity.SetContents(std::move(contents));
338  ASSERT_TRUE(OpenPlaygroundHere(std::move(entity)));
339 }

References impeller::Entity::kClamp, impeller::LineTo(), impeller::Matrix::MakeScale(), impeller::Geometry::MakeStrokePath(), impeller::MoveTo(), impeller::PathBuilder::MoveTo(), impeller::Entity::SetContents(), and impeller::Entity::SetTransform().

◆ TEST_P() [374/456]

impeller::testing::TEST_P ( EntityTest  ,
SweepGradientContentsIsOpaque   
)

Definition at line 2313 of file entity_unittests.cc.

2313  {
2314  RadialGradientContents contents;
2315  contents.SetColors({Color::CornflowerBlue()});
2316  ASSERT_TRUE(contents.IsOpaque());
2317  contents.SetColors({Color::CornflowerBlue().WithAlpha(0.5)});
2318  ASSERT_FALSE(contents.IsOpaque());
2319  contents.SetColors({Color::CornflowerBlue()});
2320  contents.SetTileMode(Entity::TileMode::kDecal);
2321  ASSERT_FALSE(contents.IsOpaque());
2322 }

References impeller::Color::CornflowerBlue(), impeller::RadialGradientContents::IsOpaque(), impeller::Entity::kDecal, impeller::RadialGradientContents::SetColors(), impeller::RadialGradientContents::SetTileMode(), and impeller::Color::WithAlpha().

◆ TEST_P() [375/456]

impeller::testing::TEST_P ( EntityTest  ,
TextContentsCeilsGlyphScaleToDecimal   
)

Definition at line 2362 of file entity_unittests.cc.

2362  {
2363  ASSERT_EQ(TextFrame::RoundScaledFontSize(0.4321111f, 12), 0.43f);
2364  ASSERT_EQ(TextFrame::RoundScaledFontSize(0.5321111f, 12), 0.53f);
2365  ASSERT_EQ(TextFrame::RoundScaledFontSize(2.1f, 12), 2.1f);
2366  ASSERT_EQ(TextFrame::RoundScaledFontSize(0.0f, 12), 0.0f);
2367  ASSERT_EQ(TextFrame::RoundScaledFontSize(100000000.0f, 12), 48.0f);
2368 }

References impeller::TextFrame::RoundScaledFontSize().

◆ TEST_P() [376/456]

impeller::testing::TEST_P ( EntityTest  ,
ThreeStrokesInOnePath   
)

Definition at line 301 of file entity_unittests.cc.

301  {
302  Path path = PathBuilder{}
303  .MoveTo({100, 100})
304  .LineTo({100, 200})
305  .MoveTo({100, 300})
306  .LineTo({100, 400})
307  .MoveTo({100, 500})
308  .LineTo({100, 600})
309  .TakePath();
310 
311  Entity entity;
312  entity.SetTransform(Matrix::MakeScale(GetContentScale()));
313  auto contents = std::make_unique<SolidColorContents>();
314  contents->SetGeometry(Geometry::MakeStrokePath(path, 5.0));
315  contents->SetColor(Color::Red());
316  entity.SetContents(std::move(contents));
317  ASSERT_TRUE(OpenPlaygroundHere(std::move(entity)));
318 }

References impeller::LineTo(), impeller::Matrix::MakeScale(), impeller::Geometry::MakeStrokePath(), impeller::MoveTo(), impeller::PathBuilder::MoveTo(), impeller::Color::Red(), impeller::Entity::SetContents(), and impeller::Entity::SetTransform().

◆ TEST_P() [377/456]

impeller::testing::TEST_P ( EntityTest  ,
TiledTextureContentsIsOpaque   
)

Definition at line 2324 of file entity_unittests.cc.

2324  {
2325  auto bay_bridge = CreateTextureForFixture("bay_bridge.jpg");
2326  TiledTextureContents contents;
2327  contents.SetTexture(bay_bridge);
2328  // This is a placeholder test. Images currently never decompress as opaque
2329  // (whether in Flutter or the playground), and so this should currently always
2330  // return false in practice.
2331  ASSERT_FALSE(contents.IsOpaque());
2332 }

References impeller::TiledTextureContents::IsOpaque(), and impeller::TiledTextureContents::SetTexture().

◆ TEST_P() [378/456]

impeller::testing::TEST_P ( EntityTest  ,
TiledTextureContentsRendersWithCorrectPipeline   
)

Definition at line 20 of file tiled_texture_contents_unittests.cc.

20  {
21  TextureDescriptor texture_desc;
22  texture_desc.size = {100, 100};
23  texture_desc.type = TextureType::kTexture2D;
24  texture_desc.format = PixelFormat::kR8G8B8A8UNormInt;
25  texture_desc.storage_mode = StorageMode::kDevicePrivate;
26  auto texture =
27  GetContext()->GetResourceAllocator()->CreateTexture(texture_desc);
28 
29  TiledTextureContents contents;
30  contents.SetTexture(texture);
31  contents.SetGeometry(Geometry::MakeCover());
32 
33  auto content_context = GetContentContext();
34  auto buffer = content_context->GetContext()->CreateCommandBuffer();
35  auto render_target =
36  GetContentContext()->GetRenderTargetCache()->CreateOffscreenMSAA(
37  *content_context->GetContext(), {100, 100},
38  /*mip_count=*/1);
39  auto render_pass = buffer->CreateRenderPass(render_target);
40  auto recording_pass = std::make_shared<RecordingRenderPass>(
41  render_pass, GetContext(), render_target);
42 
43  ASSERT_TRUE(contents.Render(*GetContentContext(), {}, *recording_pass));
44  const std::vector<Command>& commands = recording_pass->GetCommands();
45 
46  ASSERT_EQ(commands.size(), 1u);
47  EXPECT_TRUE(commands[0].pipeline->GetDescriptor().GetLabel().find(
48  "TextureFill Pipeline") != std::string::npos);
49 
50  if (GetParam() == PlaygroundBackend::kMetal) {
51  recording_pass->EncodeCommands();
52  }
53 }

References impeller::TextureDescriptor::format, impeller::kDevicePrivate, impeller::kMetal, impeller::kR8G8B8A8UNormInt, impeller::kTexture2D, impeller::Geometry::MakeCover(), impeller::TiledTextureContents::Render(), impeller::ColorSourceContents::SetGeometry(), impeller::TiledTextureContents::SetTexture(), impeller::TextureDescriptor::size, impeller::TextureDescriptor::storage_mode, and impeller::TextureDescriptor::type.

◆ TEST_P() [379/456]

impeller::testing::TEST_P ( EntityTest  ,
TiledTextureContentsRendersWithCorrectPipelineExternalOES   
)

Definition at line 57 of file tiled_texture_contents_unittests.cc.

57  {
58  if (GetParam() != PlaygroundBackend::kOpenGLES) {
59  GTEST_SKIP_(
60  "External OES textures are only valid for the OpenGLES backend.");
61  }
62 
63  TextureDescriptor texture_desc;
64  texture_desc.size = {100, 100};
65  texture_desc.type = TextureType::kTextureExternalOES;
66  texture_desc.format = PixelFormat::kR8G8B8A8UNormInt;
67  texture_desc.storage_mode = StorageMode::kDevicePrivate;
68  auto texture =
69  GetContext()->GetResourceAllocator()->CreateTexture(texture_desc);
70 
71  TiledTextureContents contents;
72  contents.SetTexture(texture);
73  contents.SetGeometry(Geometry::MakeCover());
74 
75  auto content_context = GetContentContext();
76  auto buffer = content_context->GetContext()->CreateCommandBuffer();
77  auto render_target =
78  GetContentContext()->GetRenderTargetCache()->CreateOffscreenMSAA(
79  *content_context->GetContext(), {100, 100},
80  /*mip_count=*/1);
81  auto render_pass = buffer->CreateRenderPass(render_target);
82 
83  ASSERT_TRUE(contents.Render(*GetContentContext(), {}, *render_pass));
84  const std::vector<Command>& commands = render_pass->GetCommands();
85 
86  ASSERT_EQ(commands.size(), 1u);
87  EXPECT_TRUE(commands[0].pipeline->GetDescriptor().GetLabel().find(
88  "TiledTextureFillExternal Pipeline") != std::string::npos);
89 }

References impeller::TextureDescriptor::format, impeller::kDevicePrivate, impeller::kOpenGLES, impeller::kR8G8B8A8UNormInt, impeller::kTextureExternalOES, impeller::Geometry::MakeCover(), impeller::TiledTextureContents::Render(), impeller::ColorSourceContents::SetGeometry(), impeller::TiledTextureContents::SetTexture(), impeller::TextureDescriptor::size, impeller::TextureDescriptor::storage_mode, and impeller::TextureDescriptor::type.

◆ TEST_P() [380/456]

impeller::testing::TEST_P ( EntityTest  ,
TriangleInsideASquare   
)

Definition at line 341 of file entity_unittests.cc.

341  {
342  auto callback = [&](ContentContext& context, RenderPass& pass) {
343  Point offset(100, 100);
344 
345  static PlaygroundPoint point_a(Point(10, 10) + offset, 20, Color::White());
346  Point a = DrawPlaygroundPoint(point_a);
347  static PlaygroundPoint point_b(Point(210, 10) + offset, 20, Color::White());
348  Point b = DrawPlaygroundPoint(point_b);
349  static PlaygroundPoint point_c(Point(210, 210) + offset, 20,
350  Color::White());
351  Point c = DrawPlaygroundPoint(point_c);
352  static PlaygroundPoint point_d(Point(10, 210) + offset, 20, Color::White());
353  Point d = DrawPlaygroundPoint(point_d);
354  static PlaygroundPoint point_e(Point(50, 50) + offset, 20, Color::White());
355  Point e = DrawPlaygroundPoint(point_e);
356  static PlaygroundPoint point_f(Point(100, 50) + offset, 20, Color::White());
357  Point f = DrawPlaygroundPoint(point_f);
358  static PlaygroundPoint point_g(Point(50, 150) + offset, 20, Color::White());
359  Point g = DrawPlaygroundPoint(point_g);
360  Path path = PathBuilder{}
361  .MoveTo(a)
362  .LineTo(b)
363  .LineTo(c)
364  .LineTo(d)
365  .Close()
366  .MoveTo(e)
367  .LineTo(f)
368  .LineTo(g)
369  .Close()
370  .TakePath();
371 
372  Entity entity;
373  entity.SetTransform(Matrix::MakeScale(GetContentScale()));
374  auto contents = std::make_unique<SolidColorContents>();
375  contents->SetGeometry(Geometry::MakeStrokePath(path, 20.0));
376  contents->SetColor(Color::Red());
377  entity.SetContents(std::move(contents));
378 
379  return entity.Render(context, pass);
380  };
381  ASSERT_TRUE(OpenPlaygroundHere(callback));
382 }

References impeller::saturated::b, impeller::PathBuilder::Close(), impeller::DrawPlaygroundPoint(), impeller::PathBuilder::LineTo(), impeller::Matrix::MakeScale(), impeller::Geometry::MakeStrokePath(), impeller::PathBuilder::MoveTo(), offset, impeller::Color::Red(), impeller::Entity::Render(), impeller::Entity::SetContents(), impeller::Entity::SetTransform(), impeller::PathBuilder::TakePath(), and impeller::Color::White().

◆ TEST_P() [381/456]

impeller::testing::TEST_P ( EntityTest  ,
YUVToRGBFilter   
)

Definition at line 1916 of file entity_unittests.cc.

1916  {
1917  if (GetParam() == PlaygroundBackend::kOpenGLES) {
1918  // TODO(114588) : Support YUV to RGB filter on OpenGLES backend.
1919  GTEST_SKIP_("YUV to RGB filter is not supported on OpenGLES backend yet.");
1920  }
1921 
1922  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
1923  YUVColorSpace yuv_color_space_array[2]{YUVColorSpace::kBT601FullRange,
1924  YUVColorSpace::kBT601LimitedRange};
1925  for (int i = 0; i < 2; i++) {
1926  auto yuv_color_space = yuv_color_space_array[i];
1927  auto textures =
1928  CreateTestYUVTextures(GetContext().get(), yuv_color_space);
1929  auto filter_contents = FilterContents::MakeYUVToRGBFilter(
1930  textures[0], textures[1], yuv_color_space);
1931  Entity filter_entity;
1932  filter_entity.SetContents(filter_contents);
1933  auto snapshot = filter_contents->RenderToSnapshot(context, filter_entity);
1934 
1935  Entity entity;
1936  auto contents = TextureContents::MakeRect(Rect::MakeLTRB(0, 0, 256, 256));
1937  contents->SetTexture(snapshot->texture);
1938  contents->SetSourceRect(Rect::MakeSize(snapshot->texture->GetSize()));
1939  entity.SetContents(contents);
1940  entity.SetTransform(
1941  Matrix::MakeTranslation({static_cast<Scalar>(100 + 400 * i), 300}));
1942  entity.Render(context, pass);
1943  }
1944  return true;
1945  };
1946  ASSERT_TRUE(OpenPlaygroundHere(callback));
1947 }

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

impeller::testing::TEST_P ( GaussianBlurFilterContentsTest  ,
CalculateUVsSimple   
)

Definition at line 325 of file gaussian_blur_filter_contents_unittests.cc.

325  {
326  std::shared_ptr<Texture> texture = MakeTexture(ISize(100, 100));
327  auto filter_input = FilterInput::Make(texture);
328  Entity entity;
329  Quad uvs = GaussianBlurFilterContents::CalculateUVs(
330  filter_input, entity, Rect::MakeSize(ISize(100, 100)), ISize(100, 100));
331  std::optional<Rect> uvs_bounds = Rect::MakePointBounds(uvs);
332  EXPECT_TRUE(uvs_bounds.has_value());
333  if (uvs_bounds.has_value()) {
334  EXPECT_TRUE(RectNear(uvs_bounds.value(), Rect::MakeXYWH(0, 0, 1, 1)));
335  }
336 }

References impeller::GaussianBlurFilterContents::CalculateUVs(), impeller::FilterInput::Make(), impeller::TRect< Scalar >::MakePointBounds(), impeller::TRect< Scalar >::MakeSize(), impeller::TRect< Scalar >::MakeXYWH(), RectNear(), and uvs.

◆ TEST_P() [383/456]

impeller::testing::TEST_P ( GaussianBlurFilterContentsTest  ,
CoverageWithEffectTransform   
)

Definition at line 177 of file gaussian_blur_filter_contents_unittests.cc.

177  {
178  Matrix effect_transform = Matrix::MakeScale({2.0, 2.0, 1.0});
179  fml::StatusOr<Scalar> sigma_radius_1 =
180  CalculateSigmaForBlurRadius(1.0, effect_transform);
181  ASSERT_TRUE(sigma_radius_1.ok());
182  GaussianBlurFilterContents contents(
183  /*sigma_x=*/sigma_radius_1.value(),
184  /*sigma_y=*/sigma_radius_1.value(), Entity::TileMode::kDecal,
185  FilterContents::BlurStyle::kNormal, /*mask_geometry=*/nullptr);
186  std::shared_ptr<Texture> texture = MakeTexture(ISize(100, 100));
187  FilterInput::Vector inputs = {FilterInput::Make(texture)};
188  Entity entity;
189  entity.SetTransform(Matrix::MakeTranslation({100, 100, 0}));
190  std::optional<Rect> coverage =
191  contents.GetFilterCoverage(inputs, entity, effect_transform);
192  EXPECT_TRUE(coverage.has_value());
193  if (coverage.has_value()) {
194  EXPECT_RECT_NEAR(coverage.value(),
195  Rect::MakeLTRB(100 - 1, 100 - 1, 200 + 1, 200 + 1));
196  }
197 }

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

impeller::testing::TEST_P ( GaussianBlurFilterContentsTest  ,
CoverageWithTexture   
)

Definition at line 156 of file gaussian_blur_filter_contents_unittests.cc.

156  {
157  fml::StatusOr<Scalar> sigma_radius_1 =
158  CalculateSigmaForBlurRadius(1.0, Matrix());
159  ASSERT_TRUE(sigma_radius_1.ok());
160  GaussianBlurFilterContents contents(
161  /*sigma_X=*/sigma_radius_1.value(),
162  /*sigma_y=*/sigma_radius_1.value(), Entity::TileMode::kDecal,
163  FilterContents::BlurStyle::kNormal, /*mask_geometry=*/nullptr);
164  std::shared_ptr<Texture> texture = MakeTexture(ISize(100, 100));
165  FilterInput::Vector inputs = {FilterInput::Make(texture)};
166  Entity entity;
167  entity.SetTransform(Matrix::MakeTranslation({100, 100, 0}));
168  std::optional<Rect> coverage =
169  contents.GetFilterCoverage(inputs, entity, /*effect_transform=*/Matrix());
170 
171  EXPECT_TRUE(coverage.has_value());
172  if (coverage.has_value()) {
173  EXPECT_RECT_NEAR(coverage.value(), Rect::MakeLTRB(99, 99, 201, 201));
174  }
175 }

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

impeller::testing::TEST_P ( GaussianBlurFilterContentsTest  ,
RenderCoverageMatchesGetCoverage   
)

Definition at line 229 of file gaussian_blur_filter_contents_unittests.cc.

229  {
230  std::shared_ptr<Texture> texture = MakeTexture(ISize(100, 100));
231  fml::StatusOr<Scalar> sigma_radius_1 =
232  CalculateSigmaForBlurRadius(1.0, Matrix());
233  ASSERT_TRUE(sigma_radius_1.ok());
234  auto contents = std::make_unique<GaussianBlurFilterContents>(
235  sigma_radius_1.value(), sigma_radius_1.value(), Entity::TileMode::kDecal,
236  FilterContents::BlurStyle::kNormal, /*mask_geometry=*/nullptr);
237  contents->SetInputs({FilterInput::Make(texture)});
238  std::shared_ptr<ContentContext> renderer = GetContentContext();
239 
240  Entity entity;
241  std::optional<Entity> result =
242  contents->GetEntity(*renderer, entity, /*coverage_hint=*/{});
243  EXPECT_TRUE(result.has_value());
244  if (result.has_value()) {
245  EXPECT_EQ(result.value().GetBlendMode(), BlendMode::kSourceOver);
246  std::optional<Rect> result_coverage = result.value().GetCoverage();
247  std::optional<Rect> contents_coverage = contents->GetCoverage(entity);
248  EXPECT_TRUE(result_coverage.has_value());
249  EXPECT_TRUE(contents_coverage.has_value());
250  if (result_coverage.has_value() && contents_coverage.has_value()) {
251  EXPECT_TRUE(RectNear(contents_coverage.value(),
252  Rect::MakeLTRB(-1, -1, 101, 101)));
253  EXPECT_TRUE(
254  RectNear(result_coverage.value(), Rect::MakeLTRB(-1, -1, 101, 101)));
255  }
256  }
257 }

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

◆ TEST_P() [386/456]

impeller::testing::TEST_P ( GaussianBlurFilterContentsTest  ,
RenderCoverageMatchesGetCoverageRotated   
)

Definition at line 292 of file gaussian_blur_filter_contents_unittests.cc.

293  {
294  std::shared_ptr<Texture> texture = MakeTexture(ISize(400, 300));
295  fml::StatusOr<Scalar> sigma_radius_1 =
296  CalculateSigmaForBlurRadius(1.0, Matrix());
297  auto contents = std::make_unique<GaussianBlurFilterContents>(
298  sigma_radius_1.value(), sigma_radius_1.value(), Entity::TileMode::kDecal,
299  FilterContents::BlurStyle::kNormal, /*mask_geometry=*/nullptr);
300  contents->SetInputs({FilterInput::Make(texture)});
301  std::shared_ptr<ContentContext> renderer = GetContentContext();
302 
303  Entity entity;
304  // Rotate around the top left corner, then push it over to (100, 100).
305  entity.SetTransform(Matrix::MakeTranslation({400, 100, 0}) *
306  Matrix::MakeRotationZ(Degrees(90.0)));
307  std::optional<Entity> result =
308  contents->GetEntity(*renderer, entity, /*coverage_hint=*/{});
309  EXPECT_TRUE(result.has_value());
310  if (result.has_value()) {
311  EXPECT_EQ(result.value().GetBlendMode(), BlendMode::kSourceOver);
312  std::optional<Rect> result_coverage = result.value().GetCoverage();
313  std::optional<Rect> contents_coverage = contents->GetCoverage(entity);
314  EXPECT_TRUE(result_coverage.has_value());
315  EXPECT_TRUE(contents_coverage.has_value());
316  if (result_coverage.has_value() && contents_coverage.has_value()) {
317  EXPECT_TRUE(RectNear(contents_coverage.value(),
318  Rect::MakeLTRB(99, 99, 401, 501)));
319  EXPECT_TRUE(
320  RectNear(result_coverage.value(), Rect::MakeLTRB(99, 99, 401, 501)));
321  }
322  }
323 }

References impeller::Entity::kDecal, impeller::FilterContents::kNormal, impeller::kSourceOver, impeller::FilterInput::Make(), impeller::TRect< Scalar >::MakeLTRB(), impeller::Matrix::MakeRotationZ(), impeller::Matrix::MakeTranslation(), RectNear(), and impeller::Entity::SetTransform().

◆ TEST_P() [387/456]

impeller::testing::TEST_P ( GaussianBlurFilterContentsTest  ,
RenderCoverageMatchesGetCoverageTranslate   
)

Definition at line 259 of file gaussian_blur_filter_contents_unittests.cc.

260  {
261  std::shared_ptr<Texture> texture = MakeTexture(ISize(100, 100));
262  fml::StatusOr<Scalar> sigma_radius_1 =
263  CalculateSigmaForBlurRadius(1.0, Matrix());
264  ASSERT_TRUE(sigma_radius_1.ok());
265  auto contents = std::make_unique<GaussianBlurFilterContents>(
266  sigma_radius_1.value(), sigma_radius_1.value(), Entity::TileMode::kDecal,
267  FilterContents::BlurStyle::kNormal, /*mask_geometry=*/nullptr);
268  contents->SetInputs({FilterInput::Make(texture)});
269  std::shared_ptr<ContentContext> renderer = GetContentContext();
270 
271  Entity entity;
272  entity.SetTransform(Matrix::MakeTranslation({100, 200, 0}));
273  std::optional<Entity> result =
274  contents->GetEntity(*renderer, entity, /*coverage_hint=*/{});
275 
276  EXPECT_TRUE(result.has_value());
277  if (result.has_value()) {
278  EXPECT_EQ(result.value().GetBlendMode(), BlendMode::kSourceOver);
279  std::optional<Rect> result_coverage = result.value().GetCoverage();
280  std::optional<Rect> contents_coverage = contents->GetCoverage(entity);
281  EXPECT_TRUE(result_coverage.has_value());
282  EXPECT_TRUE(contents_coverage.has_value());
283  if (result_coverage.has_value() && contents_coverage.has_value()) {
284  EXPECT_TRUE(RectNear(contents_coverage.value(),
285  Rect::MakeLTRB(99, 199, 201, 301)));
286  EXPECT_TRUE(
287  RectNear(result_coverage.value(), Rect::MakeLTRB(99, 199, 201, 301)));
288  }
289  }
290 }

References impeller::Entity::kDecal, impeller::FilterContents::kNormal, impeller::kSourceOver, impeller::FilterInput::Make(), impeller::TRect< Scalar >::MakeLTRB(), impeller::Matrix::MakeTranslation(), RectNear(), and impeller::Entity::SetTransform().

◆ TEST_P() [388/456]

impeller::testing::TEST_P ( GaussianBlurFilterContentsTest  ,
TextureContentsWithDestinationRect   
)

Definition at line 338 of file gaussian_blur_filter_contents_unittests.cc.

338  {
339  std::shared_ptr<Texture> texture = MakeTexture(ISize(100, 100));
340  auto texture_contents = std::make_shared<TextureContents>();
341  texture_contents->SetSourceRect(Rect::MakeSize(texture->GetSize()));
342  texture_contents->SetTexture(texture);
343  texture_contents->SetDestinationRect(Rect::MakeXYWH(
344  50, 40, texture->GetSize().width, texture->GetSize().height));
345 
346  fml::StatusOr<Scalar> sigma_radius_1 =
347  CalculateSigmaForBlurRadius(1.0, Matrix());
348  auto contents = std::make_unique<GaussianBlurFilterContents>(
349  sigma_radius_1.value(), sigma_radius_1.value(), Entity::TileMode::kDecal,
350  FilterContents::BlurStyle::kNormal, /*mask_geometry=*/nullptr);
351  contents->SetInputs({FilterInput::Make(texture_contents)});
352  std::shared_ptr<ContentContext> renderer = GetContentContext();
353 
354  Entity entity;
355  std::optional<Entity> result =
356  contents->GetEntity(*renderer, entity, /*coverage_hint=*/{});
357  EXPECT_TRUE(result.has_value());
358  if (result.has_value()) {
359  EXPECT_EQ(result.value().GetBlendMode(), BlendMode::kSourceOver);
360  std::optional<Rect> result_coverage = result.value().GetCoverage();
361  std::optional<Rect> contents_coverage = contents->GetCoverage(entity);
362  EXPECT_TRUE(result_coverage.has_value());
363  EXPECT_TRUE(contents_coverage.has_value());
364  if (result_coverage.has_value() && contents_coverage.has_value()) {
365  EXPECT_TRUE(RectNear(result_coverage.value(), contents_coverage.value()));
366  EXPECT_TRUE(RectNear(result_coverage.value(),
367  Rect::MakeLTRB(49.f, 39.f, 151.f, 141.f)));
368  }
369  }
370 }

References impeller::Entity::kDecal, impeller::FilterContents::kNormal, impeller::kSourceOver, impeller::FilterInput::Make(), impeller::TRect< Scalar >::MakeLTRB(), impeller::TRect< Scalar >::MakeSize(), impeller::TRect< Scalar >::MakeXYWH(), and RectNear().

◆ TEST_P() [389/456]

impeller::testing::TEST_P ( GaussianBlurFilterContentsTest  ,
TextureContentsWithDestinationRectScaled   
)

Definition at line 372 of file gaussian_blur_filter_contents_unittests.cc.

373  {
374  std::shared_ptr<Texture> texture = MakeTexture(ISize(100, 100));
375  auto texture_contents = std::make_shared<TextureContents>();
376  texture_contents->SetSourceRect(Rect::MakeSize(texture->GetSize()));
377  texture_contents->SetTexture(texture);
378  texture_contents->SetDestinationRect(Rect::MakeXYWH(
379  50, 40, texture->GetSize().width, texture->GetSize().height));
380 
381  fml::StatusOr<Scalar> sigma_radius_1 =
382  CalculateSigmaForBlurRadius(1.0, Matrix());
383  auto contents = std::make_unique<GaussianBlurFilterContents>(
384  sigma_radius_1.value(), sigma_radius_1.value(), Entity::TileMode::kDecal,
385  FilterContents::BlurStyle::kNormal,
386  /*mask_geometry=*/nullptr);
387  contents->SetInputs({FilterInput::Make(texture_contents)});
388  std::shared_ptr<ContentContext> renderer = GetContentContext();
389 
390  Entity entity;
391  entity.SetTransform(Matrix::MakeScale({2.0, 2.0, 1.0}));
392  std::optional<Entity> result =
393  contents->GetEntity(*renderer, entity, /*coverage_hint=*/{});
394  EXPECT_TRUE(result.has_value());
395  if (result.has_value()) {
396  EXPECT_EQ(result.value().GetBlendMode(), BlendMode::kSourceOver);
397  std::optional<Rect> result_coverage = result.value().GetCoverage();
398  std::optional<Rect> contents_coverage = contents->GetCoverage(entity);
399  EXPECT_TRUE(result_coverage.has_value());
400  EXPECT_TRUE(contents_coverage.has_value());
401  if (result_coverage.has_value() && contents_coverage.has_value()) {
402  EXPECT_TRUE(RectNear(result_coverage.value(), contents_coverage.value()));
403  // Scaling a blurred entity doesn't seem to scale the blur radius linearly
404  // when comparing results with rrect_blur. That's why this is not
405  // Rect::MakeXYWH(98.f, 78.f, 204.0f, 204.f).
406  EXPECT_TRUE(RectNear(contents_coverage.value(),
407  Rect::MakeXYWH(94.f, 74.f, 212.0f, 212.f)));
408  }
409  }
410 }

References impeller::Entity::kDecal, impeller::FilterContents::kNormal, impeller::kSourceOver, impeller::FilterInput::Make(), impeller::Matrix::MakeScale(), impeller::TRect< Scalar >::MakeSize(), impeller::TRect< Scalar >::MakeXYWH(), RectNear(), and impeller::Entity::SetTransform().

◆ TEST_P() [390/456]

impeller::testing::TEST_P ( GaussianBlurFilterContentsTest  ,
TextureContentsWithEffectTransform   
)

Definition at line 412 of file gaussian_blur_filter_contents_unittests.cc.

412  {
413  Matrix effect_transform = Matrix::MakeScale({2.0, 2.0, 1.0});
414  std::shared_ptr<Texture> texture = MakeTexture(ISize(100, 100));
415  auto texture_contents = std::make_shared<TextureContents>();
416  texture_contents->SetSourceRect(Rect::MakeSize(texture->GetSize()));
417  texture_contents->SetTexture(texture);
418  texture_contents->SetDestinationRect(Rect::MakeXYWH(
419  50, 40, texture->GetSize().width, texture->GetSize().height));
420 
421  fml::StatusOr<Scalar> sigma_radius_1 =
422  CalculateSigmaForBlurRadius(1.0, effect_transform);
423  ASSERT_TRUE(sigma_radius_1.ok());
424  auto contents = std::make_unique<GaussianBlurFilterContents>(
425  sigma_radius_1.value(), sigma_radius_1.value(), Entity::TileMode::kDecal,
426  FilterContents::BlurStyle::kNormal, /*mask_geometry=*/nullptr);
427  contents->SetInputs({FilterInput::Make(texture_contents)});
428  contents->SetEffectTransform(effect_transform);
429  std::shared_ptr<ContentContext> renderer = GetContentContext();
430 
431  Entity entity;
432  std::optional<Entity> result =
433  contents->GetEntity(*renderer, entity, /*coverage_hint=*/{});
434  EXPECT_TRUE(result.has_value());
435  if (result.has_value()) {
436  EXPECT_EQ(result.value().GetBlendMode(), BlendMode::kSourceOver);
437  std::optional<Rect> result_coverage = result.value().GetCoverage();
438  std::optional<Rect> contents_coverage = contents->GetCoverage(entity);
439  EXPECT_TRUE(result_coverage.has_value());
440  EXPECT_TRUE(contents_coverage.has_value());
441  if (result_coverage.has_value() && contents_coverage.has_value()) {
442  EXPECT_TRUE(RectNear(result_coverage.value(), contents_coverage.value()));
443  EXPECT_TRUE(RectNear(contents_coverage.value(),
444  Rect::MakeXYWH(49.f, 39.f, 102.f, 102.f)));
445  }
446  }
447 }

References impeller::Entity::kDecal, impeller::FilterContents::kNormal, impeller::kSourceOver, impeller::FilterInput::Make(), impeller::Matrix::MakeScale(), impeller::TRect< Scalar >::MakeSize(), impeller::TRect< Scalar >::MakeXYWH(), and RectNear().

◆ TEST_P() [391/456]

impeller::testing::TEST_P ( HostBufferTest  ,
CanEmplace   
)

Definition at line 15 of file host_buffer_unittests.cc.

15  {
16  struct Length2 {
17  uint8_t pad[2];
18  };
19  static_assert(sizeof(Length2) == 2u);
20 
21  auto buffer = HostBuffer::Create(GetContext()->GetResourceAllocator());
22 
23  for (size_t i = 0; i < 12500; i++) {
24  auto view = buffer->Emplace(Length2{});
25  ASSERT_TRUE(view);
26  ASSERT_EQ(view.range, Range(i * sizeof(Length2), 2u));
27  }
28 }

References impeller::HostBuffer::Create().

◆ TEST_P() [392/456]

impeller::testing::TEST_P ( HostBufferTest  ,
CanEmplaceWithAlignment   
)

Definition at line 30 of file host_buffer_unittests.cc.

30  {
31  struct Length2 {
32  uint8_t pad[2];
33  };
34  static_assert(sizeof(Length2) == 2);
35  struct alignas(16) Align16 {
36  uint8_t pad[2];
37  };
38  static_assert(alignof(Align16) == 16);
39  static_assert(sizeof(Align16) == 16);
40 
41  auto buffer = HostBuffer::Create(GetContext()->GetResourceAllocator());
42  ASSERT_TRUE(buffer);
43 
44  {
45  auto view = buffer->Emplace(Length2{});
46  ASSERT_TRUE(view);
47  ASSERT_EQ(view.range, Range(0u, 2u));
48  }
49 
50  {
51  auto view = buffer->Emplace(Align16{});
52  ASSERT_TRUE(view);
53  ASSERT_EQ(view.range.offset, 16u);
54  ASSERT_EQ(view.range.length, 16u);
55  }
56  {
57  auto view = buffer->Emplace(Length2{});
58  ASSERT_TRUE(view);
59  ASSERT_EQ(view.range, Range(32u, 2u));
60  }
61 
62  {
63  auto view = buffer->Emplace(Align16{});
64  ASSERT_TRUE(view);
65  ASSERT_EQ(view.range.offset, 48u);
66  ASSERT_EQ(view.range.length, 16u);
67  }
68 }

References impeller::HostBuffer::Create().

◆ TEST_P() [393/456]

impeller::testing::TEST_P ( HostBufferTest  ,
EmplaceWithProcIsAligned   
)

Definition at line 149 of file host_buffer_unittests.cc.

149  {
150  auto buffer = HostBuffer::Create(GetContext()->GetResourceAllocator());
151 
152  BufferView view = buffer->Emplace(std::array<char, 21>());
153  EXPECT_EQ(view.range, Range(0, 21));
154 
155  view = buffer->Emplace(64, 16, [](uint8_t*) {});
156  EXPECT_EQ(view.range, Range(32, 64));
157 }

References impeller::HostBuffer::Create(), and impeller::BufferView::range.

◆ TEST_P() [394/456]

impeller::testing::TEST_P ( HostBufferTest  ,
EmplacingLargerThanBlockSizeCreatesOneOffBuffer   
)

Definition at line 106 of file host_buffer_unittests.cc.

106  {
107  auto buffer = HostBuffer::Create(GetContext()->GetResourceAllocator());
108 
109  // Emplace an amount larger than the block size, to verify that the host
110  // buffer does not create a buffer.
111  auto buffer_view = buffer->Emplace(nullptr, 1024000 + 10, 0);
112 
113  EXPECT_EQ(buffer->GetStateForTest().current_buffer, 0u);
114  EXPECT_EQ(buffer->GetStateForTest().current_frame, 0u);
115  EXPECT_EQ(buffer->GetStateForTest().total_buffer_count, 1u);
116 }

References buffer_view, and impeller::HostBuffer::Create().

◆ TEST_P() [395/456]

impeller::testing::TEST_P ( HostBufferTest  ,
EmplacingLargerThanBlockSizeCreatesOneOffBufferCallback   
)

Definition at line 93 of file host_buffer_unittests.cc.

94  {
95  auto buffer = HostBuffer::Create(GetContext()->GetResourceAllocator());
96 
97  // Emplace an amount larger than the block size, to verify that the host
98  // buffer does not create a buffer.
99  auto buffer_view = buffer->Emplace(1024000 + 10, 0, [](uint8_t* data) {});
100 
101  EXPECT_EQ(buffer->GetStateForTest().current_buffer, 0u);
102  EXPECT_EQ(buffer->GetStateForTest().current_frame, 0u);
103  EXPECT_EQ(buffer->GetStateForTest().total_buffer_count, 1u);
104 }

References buffer_view, impeller::HostBuffer::Create(), and data.

◆ TEST_P() [396/456]

impeller::testing::TEST_P ( HostBufferTest  ,
HostBufferInitialState   
)

Definition at line 70 of file host_buffer_unittests.cc.

70  {
71  auto buffer = HostBuffer::Create(GetContext()->GetResourceAllocator());
72 
73  EXPECT_EQ(buffer->GetStateForTest().current_buffer, 0u);
74  EXPECT_EQ(buffer->GetStateForTest().current_frame, 0u);
75  EXPECT_EQ(buffer->GetStateForTest().total_buffer_count, 1u);
76 }

References impeller::HostBuffer::Create().

◆ TEST_P() [397/456]

impeller::testing::TEST_P ( HostBufferTest  ,
ResetIncrementsFrameCounter   
)

Definition at line 78 of file host_buffer_unittests.cc.

78  {
79  auto buffer = HostBuffer::Create(GetContext()->GetResourceAllocator());
80 
81  EXPECT_EQ(buffer->GetStateForTest().current_frame, 0u);
82 
83  buffer->Reset();
84  EXPECT_EQ(buffer->GetStateForTest().current_frame, 1u);
85 
86  buffer->Reset();
87  EXPECT_EQ(buffer->GetStateForTest().current_frame, 2u);
88 
89  buffer->Reset();
90  EXPECT_EQ(buffer->GetStateForTest().current_frame, 0u);
91 }

References impeller::HostBuffer::Create().

◆ TEST_P() [398/456]

impeller::testing::TEST_P ( HostBufferTest  ,
UnusedBuffersAreDiscardedWhenResetting   
)

Definition at line 118 of file host_buffer_unittests.cc.

118  {
119  auto buffer = HostBuffer::Create(GetContext()->GetResourceAllocator());
120 
121  // Emplace two large allocations to force the allocation of a second buffer.
122  auto buffer_view_a = buffer->Emplace(1020000, 0, [](uint8_t* data) {});
123  auto buffer_view_b = buffer->Emplace(1020000, 0, [](uint8_t* data) {});
124 
125  EXPECT_EQ(buffer->GetStateForTest().current_buffer, 1u);
126  EXPECT_EQ(buffer->GetStateForTest().total_buffer_count, 2u);
127  EXPECT_EQ(buffer->GetStateForTest().current_frame, 0u);
128 
129  // Reset until we get back to this frame.
130  for (auto i = 0; i < 3; i++) {
131  buffer->Reset();
132  }
133 
134  EXPECT_EQ(buffer->GetStateForTest().current_buffer, 0u);
135  EXPECT_EQ(buffer->GetStateForTest().total_buffer_count, 2u);
136  EXPECT_EQ(buffer->GetStateForTest().current_frame, 0u);
137 
138  // Now when we reset, the buffer should get dropped.
139  // Reset until we get back to this frame.
140  for (auto i = 0; i < 3; i++) {
141  buffer->Reset();
142  }
143 
144  EXPECT_EQ(buffer->GetStateForTest().current_buffer, 0u);
145  EXPECT_EQ(buffer->GetStateForTest().total_buffer_count, 1u);
146  EXPECT_EQ(buffer->GetStateForTest().current_frame, 0u);
147 }

References impeller::HostBuffer::Create(), and data.

◆ TEST_P() [399/456]

impeller::testing::TEST_P ( MatrixFilterContentsTest  ,
RenderCoverageMatchesGetCoverageClippedSubpassScale   
)

Definition at line 180 of file matrix_filter_contents_unittests.cc.

181  {
182  std::shared_ptr<Texture> texture = MakeTexture(ISize(100, 100));
183  MatrixFilterContents contents;
184  contents.SetInputs({FilterInput::Make(texture)});
185  contents.SetMatrix(Matrix::MakeScale({3, 3, 1}));
186  contents.SetEffectTransform(Matrix::MakeScale({2, 2, 1}));
187  contents.SetRenderingMode(
188  Entity::RenderingMode::kSubpassAppendSnapshotTransform);
189 
190  Entity entity;
191  entity.SetTransform(Matrix::MakeTranslation({100, 200, 0}));
192 
193  std::shared_ptr<ContentContext> renderer = GetContentContext();
194  std::optional<Entity> result =
195  contents.GetEntity(*renderer, entity, /*coverage_hint=*/{});
196  expectRenderCoverageEqual(result, contents.GetCoverage(entity),
197  Rect::MakeXYWH(100, 200, 300, 300));
198 }

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

impeller::testing::TEST_P ( MatrixFilterContentsTest  ,
RenderCoverageMatchesGetCoverageClippedSubpassTranslate   
)

Definition at line 143 of file matrix_filter_contents_unittests.cc.

144  {
145  std::shared_ptr<Texture> texture = MakeTexture(ISize(100, 100));
146  MatrixFilterContents contents;
147  contents.SetInputs({FilterInput::Make(texture)});
148  contents.SetMatrix(Matrix::MakeTranslation({50, 100, 0}));
149  contents.SetEffectTransform(Matrix::MakeScale({2, 2, 1}));
150  contents.SetRenderingMode(
151  Entity::RenderingMode::kSubpassAppendSnapshotTransform);
152 
153  Entity entity;
154  entity.SetTransform(Matrix::MakeTranslation({100, 200, 0}));
155 
156  std::shared_ptr<ContentContext> renderer = GetContentContext();
157  std::optional<Entity> result =
158  contents.GetEntity(*renderer, entity, /*coverage_hint=*/{});
159  expectRenderCoverageEqual(result, contents.GetCoverage(entity),
160  Rect::MakeXYWH(200, 400, 100, 100));
161 }

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

impeller::testing::TEST_P ( MatrixFilterContentsTest  ,
RenderCoverageMatchesGetCoverageIdentity   
)

Definition at line 111 of file matrix_filter_contents_unittests.cc.

111  {
112  std::shared_ptr<Texture> texture = MakeTexture(ISize(100, 100));
113  MatrixFilterContents contents;
114  contents.SetInputs({FilterInput::Make(texture)});
115 
116  Entity entity;
117  entity.SetTransform(Matrix::MakeTranslation({100, 200, 0}));
118 
119  std::shared_ptr<ContentContext> renderer = GetContentContext();
120  std::optional<Entity> result =
121  contents.GetEntity(*renderer, entity, /*coverage_hint=*/{});
122  expectRenderCoverageEqual(result, contents.GetCoverage(entity),
123  Rect::MakeXYWH(100, 200, 100, 100));
124 }

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

impeller::testing::TEST_P ( MatrixFilterContentsTest  ,
RenderCoverageMatchesGetCoverageScale   
)

Definition at line 163 of file matrix_filter_contents_unittests.cc.

163  {
164  std::shared_ptr<Texture> texture = MakeTexture(ISize(100, 100));
165  MatrixFilterContents contents;
166  contents.SetInputs({FilterInput::Make(texture)});
167  contents.SetMatrix(Matrix::MakeScale({3, 3, 1}));
168  contents.SetEffectTransform(Matrix::MakeScale({2, 2, 1}));
169 
170  Entity entity;
171  entity.SetTransform(Matrix::MakeTranslation({100, 200, 0}));
172 
173  std::shared_ptr<ContentContext> renderer = GetContentContext();
174  std::optional<Entity> result =
175  contents.GetEntity(*renderer, entity, /*coverage_hint=*/{});
176  expectRenderCoverageEqual(result, contents.GetCoverage(entity),
177  Rect::MakeXYWH(100, 200, 300, 300));
178 }

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

impeller::testing::TEST_P ( MatrixFilterContentsTest  ,
RenderCoverageMatchesGetCoverageSubpassScale   
)

Definition at line 200 of file matrix_filter_contents_unittests.cc.

200  {
201  std::shared_ptr<Texture> texture = MakeTexture(ISize(100, 100));
202  MatrixFilterContents contents;
203  contents.SetInputs({FilterInput::Make(texture)});
204  contents.SetMatrix(Matrix::MakeScale({3, 3, 1}));
205  contents.SetEffectTransform(Matrix::MakeScale({2, 2, 1}));
206  contents.SetRenderingMode(
207  Entity::RenderingMode::kSubpassPrependSnapshotTransform);
208 
209  Entity entity;
210  entity.SetTransform(Matrix::MakeTranslation({100, 200, 0}));
211 
212  std::shared_ptr<ContentContext> renderer = GetContentContext();
213  std::optional<Entity> result =
214  contents.GetEntity(*renderer, entity, /*coverage_hint=*/{});
215  expectRenderCoverageEqual(result, contents.GetCoverage(entity),
216  Rect::MakeXYWH(300, 600, 300, 300));
217 }

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

impeller::testing::TEST_P ( MatrixFilterContentsTest  ,
RenderCoverageMatchesGetCoverageTranslate   
)

Definition at line 126 of file matrix_filter_contents_unittests.cc.

126  {
127  std::shared_ptr<Texture> texture = MakeTexture(ISize(100, 100));
128  MatrixFilterContents contents;
129  contents.SetInputs({FilterInput::Make(texture)});
130  contents.SetMatrix(Matrix::MakeTranslation({50, 100, 0}));
131  contents.SetEffectTransform(Matrix::MakeScale({2, 2, 1}));
132 
133  Entity entity;
134  entity.SetTransform(Matrix::MakeTranslation({100, 200, 0}));
135 
136  std::shared_ptr<ContentContext> renderer = GetContentContext();
137  std::optional<Entity> result =
138  contents.GetEntity(*renderer, entity, /*coverage_hint=*/{});
139  expectRenderCoverageEqual(result, contents.GetCoverage(entity),
140  Rect::MakeXYWH(150, 300, 100, 100));
141 }

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

impeller::testing::TEST_P ( RendererDartTest  ,
CanCreateRenderPassAndSubmit   
)

Definition at line 302 of file renderer_dart_unittests.cc.

302  {
303  ASSERT_TRUE(RenderDartToPlayground("canCreateRenderPassAndSubmit"));
304 }

◆ TEST_P() [406/456]

impeller::testing::TEST_P ( RendererDartTest  ,
CanCreateShaderLibrary   
)

Definition at line 290 of file renderer_dart_unittests.cc.

290  {
291  ASSERT_TRUE(RunDartFunction("canCreateShaderLibrary"));
292 }

◆ TEST_P() [407/456]

impeller::testing::TEST_P ( RendererDartTest  ,
CanInstantiateFlutterGPUContext   
)

These test entries correspond to Dart functions located in flutter/impeller/fixtures/dart_tests.dart

Definition at line 286 of file renderer_dart_unittests.cc.

286  {
287  ASSERT_TRUE(RunDartFunction("instantiateDefaultContext"));
288 }

◆ TEST_P() [408/456]

impeller::testing::TEST_P ( RendererDartTest  ,
CanReflectUniformStructs   
)

Definition at line 294 of file renderer_dart_unittests.cc.

294  {
295  ASSERT_TRUE(RunDartFunction("canReflectUniformStructs"));
296 }

◆ TEST_P() [409/456]

impeller::testing::TEST_P ( RendererDartTest  ,
CanRunDartInPlaygroundFrame   
)

Definition at line 271 of file renderer_dart_unittests.cc.

271  {
272  SinglePassCallback callback = [&](RenderPass& pass) {
273  ImGui::Begin("Dart test", nullptr);
274  ImGui::Text(
275  "This test executes Dart code during the playground frame callback.");
276  ImGui::End();
277 
278  return RunDartFunction("sayHi");
279  };
280  ASSERT_TRUE(OpenPlaygroundHere(callback));
281 }

◆ TEST_P() [410/456]

impeller::testing::TEST_P ( RendererDartTest  ,
UniformBindFailsForInvalidHostBufferOffset   
)

Definition at line 298 of file renderer_dart_unittests.cc.

298  {
299  ASSERT_TRUE(RunDartFunction("uniformBindFailsForInvalidHostBufferOffset"));
300 }

◆ TEST_P() [411/456]

impeller::testing::TEST_P ( RendererTest  ,
ArrayUniforms   
)

Definition at line 997 of file renderer_unittests.cc.

997  {
998  using VS = ArrayVertexShader;
999  using FS = ArrayFragmentShader;
1000 
1001  auto context = GetContext();
1002  auto pipeline_descriptor =
1003  PipelineBuilder<VS, FS>::MakeDefaultPipelineDescriptor(*context);
1004  ASSERT_TRUE(pipeline_descriptor.has_value());
1005  pipeline_descriptor->SetSampleCount(SampleCount::kCount4);
1006  pipeline_descriptor->SetStencilAttachmentDescriptors(std::nullopt);
1007  auto pipeline =
1008  context->GetPipelineLibrary()->GetPipeline(pipeline_descriptor).Get();
1009  ASSERT_TRUE(pipeline && pipeline->IsValid());
1010 
1011  auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
1012  SinglePassCallback callback = [&](RenderPass& pass) {
1013  auto size = pass.GetRenderTargetSize();
1014 
1015  pass.SetPipeline(pipeline);
1016  pass.SetCommandLabel("Google Dots");
1017  VertexBufferBuilder<VS::PerVertexData> builder;
1018  builder.AddVertices({{Point()},
1019  {Point(0, size.height)},
1020  {Point(size.width, 0)},
1021  {Point(size.width, 0)},
1022  {Point(0, size.height)},
1023  {Point(size.width, size.height)}});
1024  pass.SetVertexBuffer(builder.CreateVertexBuffer(*host_buffer));
1025 
1026  VS::FrameInfo frame_info;
1027  EXPECT_EQ(pass.GetOrthographicTransform(), Matrix::MakeOrthographic(size));
1028  frame_info.mvp =
1029  pass.GetOrthographicTransform() * Matrix::MakeScale(GetContentScale());
1030  VS::BindFrameInfo(pass, host_buffer->EmplaceUniform(frame_info));
1031 
1032  auto time = GetSecondsElapsed();
1033  auto y_pos = [&time](float x) {
1034  return 400 + 10 * std::cos(time * 5 + x / 6);
1035  };
1036 
1037  FS::FragInfo fs_uniform = {
1038  .circle_positions = {Point(430, y_pos(0)), Point(480, y_pos(1)),
1039  Point(530, y_pos(2)), Point(580, y_pos(3))},
1040  .colors = {Color::MakeRGBA8(66, 133, 244, 255),
1041  Color::MakeRGBA8(219, 68, 55, 255),
1042  Color::MakeRGBA8(244, 180, 0, 255),
1043  Color::MakeRGBA8(15, 157, 88, 255)},
1044  };
1045  FS::BindFragInfo(pass, host_buffer->EmplaceUniform(fs_uniform));
1046 
1047  pass.Draw();
1048  host_buffer->Reset();
1049  return true;
1050  };
1051  OpenPlaygroundHere(callback);
1052 }

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(), and impeller::Matrix::MakeScale().

◆ TEST_P() [412/456]

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(context->GetResourceAllocator());
149 
150  // Specify the vertex buffer information.
151  VertexBufferBuilder<VS::PerVertexData> vertex_buffer_builder;
152  vertex_buffer_builder.AddVertices({
153  {{-0.5, -0.5}, Color::Red(), Color::Green()},
154  {{0.0, 0.5}, Color::Green(), Color::Blue()},
155  {{0.5, -0.5}, Color::Blue(), Color::Red()},
156  });
157 
158  auto vertex_buffer = vertex_buffer_builder.CreateVertexBuffer(
159  *context->GetResourceAllocator());
160 
161  SinglePassCallback callback = [&](RenderPass& pass) {
162  pass.SetPipeline(pipeline);
163  pass.SetVertexBuffer(vertex_buffer);
164 
165  FS::FragInfo frag_info;
166  frag_info.time = fml::TimePoint::Now().ToEpochDelta().ToSecondsF();
167 
168  auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
169  FS::BindFragInfo(pass, host_buffer->EmplaceUniform(frag_info));
170 
171  return pass.Draw().ok();
172  };
173  OpenPlaygroundHere(callback);
174 }

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

impeller::testing::TEST_P ( RendererTest  ,
CachesRenderPassAndFramebuffer   
)

Definition at line 16 of file render_pass_cache_unittests.cc.

16  {
17  if (GetBackend() != PlaygroundBackend::kVulkan) {
18  GTEST_SKIP() << "Test only applies to Vulkan";
19  }
20 
21  auto allocator = std::make_shared<RenderTargetAllocator>(
22  GetContext()->GetResourceAllocator());
23 
24  auto render_target =
25  allocator->CreateOffscreenMSAA(*GetContext(), {100, 100}, 1);
26  auto resolve_texture =
27  render_target.GetColorAttachments().find(0u)->second.resolve_texture;
28  auto& texture_vk = TextureVK::Cast(*resolve_texture);
29 
30  EXPECT_EQ(texture_vk.GetCachedFramebuffer(), nullptr);
31  EXPECT_EQ(texture_vk.GetCachedRenderPass(), nullptr);
32 
33  auto buffer = GetContext()->CreateCommandBuffer();
34  auto render_pass = buffer->CreateRenderPass(render_target);
35 
36  EXPECT_NE(texture_vk.GetCachedFramebuffer(), nullptr);
37  EXPECT_NE(texture_vk.GetCachedRenderPass(), nullptr);
38 
39  render_pass->EncodeCommands();
40  GetContext()->GetCommandQueue()->Submit({buffer});
41 
42  // Can be reused without error.
43  auto buffer_2 = GetContext()->CreateCommandBuffer();
44  auto render_pass_2 = buffer_2->CreateRenderPass(render_target);
45 
46  EXPECT_TRUE(render_pass_2->EncodeCommands());
47  EXPECT_TRUE(GetContext()->GetCommandQueue()->Submit({buffer_2}).ok());
48 }

References impeller::BackendCast< TextureVK, Texture >::Cast(), and impeller::kVulkan.

◆ TEST_P() [414/456]

impeller::testing::TEST_P ( RendererTest  ,
CanBlitTextureToBuffer   
)

Definition at line 613 of file renderer_unittests.cc.

613  {
614  if (GetBackend() == PlaygroundBackend::kOpenGLES) {
615  GTEST_SKIP() << "Mipmap test shader not supported on GLES.";
616  }
617  auto context = GetContext();
618  ASSERT_TRUE(context);
619 
620  using VS = MipmapsVertexShader;
621  using FS = MipmapsFragmentShader;
622  auto desc = PipelineBuilder<VS, FS>::MakeDefaultPipelineDescriptor(*context);
623  ASSERT_TRUE(desc.has_value());
624  desc->SetSampleCount(SampleCount::kCount4);
625  desc->SetStencilAttachmentDescriptors(std::nullopt);
626  auto mipmaps_pipeline =
627  context->GetPipelineLibrary()->GetPipeline(std::move(desc)).Get();
628  ASSERT_TRUE(mipmaps_pipeline);
629 
630  auto bridge = CreateTextureForFixture("bay_bridge.jpg");
631  auto boston = CreateTextureForFixture("boston.jpg");
632  ASSERT_TRUE(bridge && boston);
633  const std::unique_ptr<const Sampler>& sampler =
634  context->GetSamplerLibrary()->GetSampler({});
635  ASSERT_TRUE(sampler);
636 
637  TextureDescriptor texture_desc;
638  texture_desc.storage_mode = StorageMode::kHostVisible;
639  texture_desc.format = PixelFormat::kR8G8B8A8UNormInt;
640  texture_desc.size = bridge->GetTextureDescriptor().size;
641  texture_desc.mip_count = 1u;
642  texture_desc.usage = TextureUsage::kRenderTarget |
643  TextureUsage::kShaderWrite | TextureUsage::kShaderRead;
644  DeviceBufferDescriptor device_buffer_desc;
645  device_buffer_desc.storage_mode = StorageMode::kHostVisible;
646  device_buffer_desc.size =
647  bridge->GetTextureDescriptor().GetByteSizeOfBaseMipLevel();
648  auto device_buffer =
649  context->GetResourceAllocator()->CreateBuffer(device_buffer_desc);
650 
651  // Vertex buffer.
652  VertexBufferBuilder<VS::PerVertexData> vertex_builder;
653  vertex_builder.SetLabel("Box");
654  auto size = Point(boston->GetSize());
655  vertex_builder.AddVertices({
656  {{0, 0}, {0.0, 0.0}}, // 1
657  {{size.x, 0}, {1.0, 0.0}}, // 2
658  {{size.x, size.y}, {1.0, 1.0}}, // 3
659  {{0, 0}, {0.0, 0.0}}, // 1
660  {{size.x, size.y}, {1.0, 1.0}}, // 3
661  {{0, size.y}, {0.0, 1.0}}, // 4
662  });
663  auto vertex_buffer =
664  vertex_builder.CreateVertexBuffer(*context->GetResourceAllocator());
665  ASSERT_TRUE(vertex_buffer);
666 
667  auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
668  Renderer::RenderCallback callback = [&](RenderTarget& render_target) {
669  {
670  auto buffer = context->CreateCommandBuffer();
671  if (!buffer) {
672  return false;
673  }
674  buffer->SetLabel("Playground Command Buffer");
675  auto pass = buffer->CreateBlitPass();
676  if (!pass) {
677  return false;
678  }
679  pass->SetLabel("Playground Blit Pass");
680 
681  if (render_target.GetColorAttachments().empty()) {
682  return false;
683  }
684 
685  // Blit `bridge` to the top left corner of the texture.
686  pass->AddCopy(bridge, device_buffer);
687  pass->EncodeCommands(context->GetResourceAllocator());
688 
689  if (!context->GetCommandQueue()->Submit({buffer}).ok()) {
690  return false;
691  }
692  }
693 
694  {
695  auto buffer = context->CreateCommandBuffer();
696  if (!buffer) {
697  return false;
698  }
699  buffer->SetLabel("Playground Command Buffer");
700 
701  auto pass = buffer->CreateRenderPass(render_target);
702  if (!pass) {
703  return false;
704  }
705  pass->SetLabel("Playground Render Pass");
706  {
707  pass->SetCommandLabel("Image");
708  pass->SetPipeline(mipmaps_pipeline);
709  pass->SetVertexBuffer(vertex_buffer);
710 
711  VS::FrameInfo frame_info;
712  EXPECT_EQ(pass->GetOrthographicTransform(),
713  Matrix::MakeOrthographic(pass->GetRenderTargetSize()));
714  frame_info.mvp = pass->GetOrthographicTransform() *
715  Matrix::MakeScale(GetContentScale());
716  VS::BindFrameInfo(*pass, host_buffer->EmplaceUniform(frame_info));
717 
718  FS::FragInfo frag_info;
719  frag_info.lod = 0;
720  FS::BindFragInfo(*pass, host_buffer->EmplaceUniform(frag_info));
721 
722  const std::unique_ptr<const Sampler>& sampler =
723  context->GetSamplerLibrary()->GetSampler({});
724  auto buffer_view = DeviceBuffer::AsBufferView(device_buffer);
725  auto texture =
726  context->GetResourceAllocator()->CreateTexture(texture_desc);
727  if (!texture->SetContents(device_buffer->OnGetContents(),
728  buffer_view.range.length)) {
729  VALIDATION_LOG << "Could not upload texture to device memory";
730  return false;
731  }
732  FS::BindTex(*pass, texture, sampler);
733 
734  pass->Draw().ok();
735  }
736  pass->EncodeCommands();
737  if (!context->GetCommandQueue()->Submit({buffer}).ok()) {
738  return false;
739  }
740  }
741  host_buffer->Reset();
742  return true;
743  };
744  OpenPlaygroundHere(callback);
745 }

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

impeller::testing::TEST_P ( RendererTest  ,
CanBlitTextureToTexture   
)

Definition at line 498 of file renderer_unittests.cc.

498  {
499  if (GetBackend() == PlaygroundBackend::kOpenGLES) {
500  GTEST_SKIP() << "Mipmap test shader not supported on GLES.";
501  }
502  auto context = GetContext();
503  ASSERT_TRUE(context);
504 
505  using VS = MipmapsVertexShader;
506  using FS = MipmapsFragmentShader;
507  auto desc = PipelineBuilder<VS, FS>::MakeDefaultPipelineDescriptor(*context);
508  ASSERT_TRUE(desc.has_value());
509  desc->SetSampleCount(SampleCount::kCount4);
510  desc->SetStencilAttachmentDescriptors(std::nullopt);
511  auto mipmaps_pipeline =
512  context->GetPipelineLibrary()->GetPipeline(std::move(desc)).Get();
513  ASSERT_TRUE(mipmaps_pipeline);
514 
515  TextureDescriptor texture_desc;
516  texture_desc.storage_mode = StorageMode::kHostVisible;
517  texture_desc.format = PixelFormat::kR8G8B8A8UNormInt;
518  texture_desc.size = {800, 600};
519  texture_desc.mip_count = 1u;
520  texture_desc.usage = TextureUsage::kRenderTarget | TextureUsage::kShaderRead;
521  auto texture = context->GetResourceAllocator()->CreateTexture(texture_desc);
522  ASSERT_TRUE(texture);
523 
524  auto bridge = CreateTextureForFixture("bay_bridge.jpg");
525  auto boston = CreateTextureForFixture("boston.jpg");
526  ASSERT_TRUE(bridge && boston);
527  const std::unique_ptr<const Sampler>& sampler =
528  context->GetSamplerLibrary()->GetSampler({});
529  ASSERT_TRUE(sampler);
530 
531  // Vertex buffer.
532  VertexBufferBuilder<VS::PerVertexData> vertex_builder;
533  vertex_builder.SetLabel("Box");
534  auto size = Point(boston->GetSize());
535  vertex_builder.AddVertices({
536  {{0, 0}, {0.0, 0.0}}, // 1
537  {{size.x, 0}, {1.0, 0.0}}, // 2
538  {{size.x, size.y}, {1.0, 1.0}}, // 3
539  {{0, 0}, {0.0, 0.0}}, // 1
540  {{size.x, size.y}, {1.0, 1.0}}, // 3
541  {{0, size.y}, {0.0, 1.0}}, // 4
542  });
543  auto vertex_buffer =
544  vertex_builder.CreateVertexBuffer(*context->GetResourceAllocator());
545  ASSERT_TRUE(vertex_buffer);
546 
547  auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
548  Renderer::RenderCallback callback = [&](RenderTarget& render_target) {
549  auto buffer = context->CreateCommandBuffer();
550  if (!buffer) {
551  return false;
552  }
553  buffer->SetLabel("Playground Command Buffer");
554 
555  {
556  auto pass = buffer->CreateBlitPass();
557  if (!pass) {
558  return false;
559  }
560  pass->SetLabel("Playground Blit Pass");
561 
562  if (render_target.GetColorAttachments().empty()) {
563  return false;
564  }
565 
566  // Blit `bridge` to the top left corner of the texture.
567  pass->AddCopy(bridge, texture);
568 
569  if (!pass->EncodeCommands(context->GetResourceAllocator())) {
570  return false;
571  }
572  }
573 
574  {
575  auto pass = buffer->CreateRenderPass(render_target);
576  if (!pass) {
577  return false;
578  }
579  pass->SetLabel("Playground Render Pass");
580  {
581  pass->SetCommandLabel("Image");
582  pass->SetPipeline(mipmaps_pipeline);
583  pass->SetVertexBuffer(vertex_buffer);
584 
585  VS::FrameInfo frame_info;
586  EXPECT_EQ(pass->GetOrthographicTransform(),
587  Matrix::MakeOrthographic(pass->GetRenderTargetSize()));
588  frame_info.mvp = pass->GetOrthographicTransform() *
589  Matrix::MakeScale(GetContentScale());
590  VS::BindFrameInfo(*pass, host_buffer->EmplaceUniform(frame_info));
591 
592  FS::FragInfo frag_info;
593  frag_info.lod = 0;
594  FS::BindFragInfo(*pass, host_buffer->EmplaceUniform(frag_info));
595 
596  auto& sampler = context->GetSamplerLibrary()->GetSampler({});
597  FS::BindTex(*pass, texture, sampler);
598 
599  pass->Draw();
600  }
601  pass->EncodeCommands();
602  }
603 
604  if (!context->GetCommandQueue()->Submit({buffer}).ok()) {
605  return false;
606  }
607  host_buffer->Reset();
608  return true;
609  };
610  OpenPlaygroundHere(callback);
611 }

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

impeller::testing::TEST_P ( RendererTest  ,
CanCreateBoxPrimitive   
)

Definition at line 54 of file renderer_unittests.cc.

54  {
55  using VS = BoxFadeVertexShader;
56  using FS = BoxFadeFragmentShader;
57  auto context = GetContext();
58  ASSERT_TRUE(context);
59  using BoxPipelineBuilder = PipelineBuilder<VS, FS>;
60  auto desc = BoxPipelineBuilder::MakeDefaultPipelineDescriptor(*context);
61  ASSERT_TRUE(desc.has_value());
62  desc->SetSampleCount(SampleCount::kCount4);
63  desc->SetStencilAttachmentDescriptors(std::nullopt);
64 
65  // Vertex buffer.
66  VertexBufferBuilder<VS::PerVertexData> vertex_builder;
67  vertex_builder.SetLabel("Box");
68  vertex_builder.AddVertices({
69  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
70  {{800, 100, 0.0}, {1.0, 0.0}}, // 2
71  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
72  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
73  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
74  {{100, 800, 0.0}, {0.0, 1.0}}, // 4
75  });
76  auto bridge = CreateTextureForFixture("bay_bridge.jpg");
77  auto boston = CreateTextureForFixture("boston.jpg");
78  ASSERT_TRUE(bridge && boston);
79  const std::unique_ptr<const Sampler>& sampler =
80  context->GetSamplerLibrary()->GetSampler({});
81  ASSERT_TRUE(sampler);
82 
83  auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
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() [417/456]

impeller::testing::TEST_P ( RendererTest  ,
CanGenerateMipmaps   
)

Definition at line 747 of file renderer_unittests.cc.

747  {
748  if (GetBackend() == PlaygroundBackend::kOpenGLES) {
749  GTEST_SKIP() << "Mipmap test shader not supported on GLES.";
750  }
751  auto context = GetContext();
752  ASSERT_TRUE(context);
753 
754  using VS = MipmapsVertexShader;
755  using FS = MipmapsFragmentShader;
756  auto desc = PipelineBuilder<VS, FS>::MakeDefaultPipelineDescriptor(*context);
757  ASSERT_TRUE(desc.has_value());
758  desc->SetSampleCount(SampleCount::kCount4);
759  desc->SetStencilAttachmentDescriptors(std::nullopt);
760  auto mipmaps_pipeline =
761  context->GetPipelineLibrary()->GetPipeline(std::move(desc)).Get();
762  ASSERT_TRUE(mipmaps_pipeline);
763 
764  auto boston = CreateTextureForFixture("boston.jpg", true);
765  ASSERT_TRUE(boston);
766 
767  // Vertex buffer.
768  VertexBufferBuilder<VS::PerVertexData> vertex_builder;
769  vertex_builder.SetLabel("Box");
770  auto size = Point(boston->GetSize());
771  vertex_builder.AddVertices({
772  {{0, 0}, {0.0, 0.0}}, // 1
773  {{size.x, 0}, {1.0, 0.0}}, // 2
774  {{size.x, size.y}, {1.0, 1.0}}, // 3
775  {{0, 0}, {0.0, 0.0}}, // 1
776  {{size.x, size.y}, {1.0, 1.0}}, // 3
777  {{0, size.y}, {0.0, 1.0}}, // 4
778  });
779  auto vertex_buffer =
780  vertex_builder.CreateVertexBuffer(*context->GetResourceAllocator());
781  ASSERT_TRUE(vertex_buffer);
782 
783  bool first_frame = true;
784  auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
785  Renderer::RenderCallback callback = [&](RenderTarget& render_target) {
786  const char* mip_filter_names[] = {"Base", "Nearest", "Linear"};
787  const MipFilter mip_filters[] = {MipFilter::kBase, MipFilter::kNearest,
788  MipFilter::kLinear};
789  const char* min_filter_names[] = {"Nearest", "Linear"};
790  const MinMagFilter min_filters[] = {MinMagFilter::kNearest,
791  MinMagFilter::kLinear};
792 
793  // UI state.
794  static int selected_mip_filter = 1;
795  static int selected_min_filter = 0;
796  static float lod = 4.5;
797 
798  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
799  ImGui::Combo("Mip filter", &selected_mip_filter, mip_filter_names,
800  sizeof(mip_filter_names) / sizeof(char*));
801  ImGui::Combo("Min filter", &selected_min_filter, min_filter_names,
802  sizeof(min_filter_names) / sizeof(char*));
803  ImGui::SliderFloat("LOD", &lod, 0, boston->GetMipCount() - 1);
804  ImGui::End();
805 
806  auto buffer = context->CreateCommandBuffer();
807  if (!buffer) {
808  return false;
809  }
810  buffer->SetLabel("Playground Command Buffer");
811 
812  if (first_frame) {
813  auto pass = buffer->CreateBlitPass();
814  if (!pass) {
815  return false;
816  }
817  pass->SetLabel("Playground Blit Pass");
818 
819  pass->GenerateMipmap(boston, "Boston Mipmap");
820 
821  pass->EncodeCommands(context->GetResourceAllocator());
822  }
823 
824  first_frame = false;
825 
826  {
827  auto pass = buffer->CreateRenderPass(render_target);
828  if (!pass) {
829  return false;
830  }
831  pass->SetLabel("Playground Render Pass");
832  {
833  pass->SetCommandLabel("Image LOD");
834  pass->SetPipeline(mipmaps_pipeline);
835  pass->SetVertexBuffer(vertex_buffer);
836 
837  VS::FrameInfo frame_info;
838  EXPECT_EQ(pass->GetOrthographicTransform(),
839  Matrix::MakeOrthographic(pass->GetRenderTargetSize()));
840  frame_info.mvp = pass->GetOrthographicTransform() *
841  Matrix::MakeScale(GetContentScale());
842  VS::BindFrameInfo(*pass, host_buffer->EmplaceUniform(frame_info));
843 
844  FS::FragInfo frag_info;
845  frag_info.lod = lod;
846  FS::BindFragInfo(*pass, host_buffer->EmplaceUniform(frag_info));
847 
848  SamplerDescriptor sampler_desc;
849  sampler_desc.mip_filter = mip_filters[selected_mip_filter];
850  sampler_desc.min_filter = min_filters[selected_min_filter];
851  const std::unique_ptr<const Sampler>& sampler =
852  context->GetSamplerLibrary()->GetSampler(sampler_desc);
853  FS::BindTex(*pass, boston, sampler);
854 
855  pass->Draw();
856  }
857  pass->EncodeCommands();
858  }
859 
860  if (!context->GetCommandQueue()->Submit({buffer}).ok()) {
861  return false;
862  }
863  host_buffer->Reset();
864  return true;
865  };
866  OpenPlaygroundHere(callback);
867 }

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

impeller::testing::TEST_P ( RendererTest  ,
CanLookupRenderTargetProperties   
)

Definition at line 1341 of file renderer_unittests.cc.

1341  {
1342  auto context = GetContext();
1343  auto cmd_buffer = context->CreateCommandBuffer();
1344  auto render_target_cache = std::make_shared<RenderTargetAllocator>(
1345  GetContext()->GetResourceAllocator());
1346 
1347  auto render_target = render_target_cache->CreateOffscreen(
1348  *context, {100, 100}, /*mip_count=*/1);
1349  auto render_pass = cmd_buffer->CreateRenderPass(render_target);
1350 
1351  EXPECT_EQ(render_pass->GetSampleCount(), render_target.GetSampleCount());
1352  EXPECT_EQ(render_pass->GetRenderTargetPixelFormat(),
1353  render_target.GetRenderTargetPixelFormat());
1354  EXPECT_EQ(render_pass->HasStencilAttachment(),
1355  render_target.GetStencilAttachment().has_value());
1356  EXPECT_EQ(render_pass->GetRenderTargetSize(),
1357  render_target.GetRenderTargetSize());
1358  render_pass->EncodeCommands();
1359 }

◆ TEST_P() [419/456]

impeller::testing::TEST_P ( RendererTest  ,
CanRenderInstanced   
)

Definition at line 441 of file renderer_unittests.cc.

441  {
442  if (GetParam() == PlaygroundBackend::kOpenGLES) {
443  GTEST_SKIP_("Instancing is not supported on OpenGL.");
444  }
445  using VS = InstancedDrawVertexShader;
446  using FS = InstancedDrawFragmentShader;
447 
448  VertexBufferBuilder<VS::PerVertexData> builder;
449  builder.AddVertices({
450  VS::PerVertexData{Point{10, 10}},
451  VS::PerVertexData{Point{10, 110}},
452  VS::PerVertexData{Point{110, 10}},
453  VS::PerVertexData{Point{10, 110}},
454  VS::PerVertexData{Point{110, 10}},
455  VS::PerVertexData{Point{110, 110}},
456  });
457 
458  ASSERT_NE(GetContext(), nullptr);
459  auto pipeline =
460  GetContext()
461  ->GetPipelineLibrary()
462  ->GetPipeline(PipelineBuilder<VS, FS>::MakeDefaultPipelineDescriptor(
463  *GetContext())
464  ->SetSampleCount(SampleCount::kCount4)
465  .SetStencilAttachmentDescriptors(std::nullopt))
466 
467  .Get();
468  ASSERT_TRUE(pipeline && pipeline->IsValid());
469 
470  static constexpr size_t kInstancesCount = 5u;
471  VS::InstanceInfo<kInstancesCount> instances;
472  for (size_t i = 0; i < kInstancesCount; i++) {
473  instances.colors[i] = Color::Random();
474  }
475 
476  auto host_buffer = HostBuffer::Create(GetContext()->GetResourceAllocator());
477  ASSERT_TRUE(OpenPlaygroundHere([&](RenderPass& pass) -> bool {
478  pass.SetPipeline(pipeline);
479  pass.SetCommandLabel("InstancedDraw");
480 
481  VS::FrameInfo frame_info;
482  EXPECT_EQ(pass.GetOrthographicTransform(),
483  Matrix::MakeOrthographic(pass.GetRenderTargetSize()));
484  frame_info.mvp =
485  pass.GetOrthographicTransform() * Matrix::MakeScale(GetContentScale());
486  VS::BindFrameInfo(pass, host_buffer->EmplaceUniform(frame_info));
487  VS::BindInstanceInfo(pass, host_buffer->EmplaceStorageBuffer(instances));
488  pass.SetVertexBuffer(builder.CreateVertexBuffer(*host_buffer));
489 
490  pass.SetInstanceCount(kInstancesCount);
491  pass.Draw();
492 
493  host_buffer->Reset();
494  return true;
495  }));
496 }

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

impeller::testing::TEST_P ( RendererTest  ,
CanRenderMultiplePrimitives   
)

Definition at line 265 of file renderer_unittests.cc.

265  {
266  using VS = BoxFadeVertexShader;
267  using FS = BoxFadeFragmentShader;
268  auto context = GetContext();
269  ASSERT_TRUE(context);
270  using BoxPipelineBuilder = PipelineBuilder<VS, FS>;
271  auto desc = BoxPipelineBuilder::MakeDefaultPipelineDescriptor(*context);
272  ASSERT_TRUE(desc.has_value());
273  desc->SetSampleCount(SampleCount::kCount4);
274  desc->SetStencilAttachmentDescriptors(std::nullopt);
275  auto box_pipeline =
276  context->GetPipelineLibrary()->GetPipeline(std::move(desc)).Get();
277  ASSERT_TRUE(box_pipeline);
278 
279  // Vertex buffer.
280  VertexBufferBuilder<VS::PerVertexData> vertex_builder;
281  vertex_builder.SetLabel("Box");
282  vertex_builder.AddVertices({
283  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
284  {{800, 100, 0.0}, {1.0, 0.0}}, // 2
285  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
286  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
287  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
288  {{100, 800, 0.0}, {0.0, 1.0}}, // 4
289  });
290  auto vertex_buffer =
291  vertex_builder.CreateVertexBuffer(*context->GetResourceAllocator());
292  ASSERT_TRUE(vertex_buffer);
293 
294  auto bridge = CreateTextureForFixture("bay_bridge.jpg");
295  auto boston = CreateTextureForFixture("boston.jpg");
296  ASSERT_TRUE(bridge && boston);
297  const std::unique_ptr<const Sampler>& sampler =
298  context->GetSamplerLibrary()->GetSampler({});
299  ASSERT_TRUE(sampler);
300 
301  auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
302  SinglePassCallback callback = [&](RenderPass& pass) {
303  for (size_t i = 0; i < 1; i++) {
304  for (size_t j = 0; j < 1; j++) {
305  pass.SetCommandLabel("Box");
306  pass.SetPipeline(box_pipeline);
307  pass.SetVertexBuffer(vertex_buffer);
308 
309  FS::FrameInfo frame_info;
310  frame_info.current_time = GetSecondsElapsed();
311  frame_info.cursor_position = GetCursorPosition();
312  frame_info.window_size.x = GetWindowSize().width;
313  frame_info.window_size.y = GetWindowSize().height;
314 
315  FS::BindFrameInfo(pass, host_buffer->EmplaceUniform(frame_info));
316  FS::BindContents1(pass, boston, sampler);
317  FS::BindContents2(pass, bridge, sampler);
318 
319  VS::UniformBuffer uniforms;
320  EXPECT_EQ(pass.GetOrthographicTransform(),
321  Matrix::MakeOrthographic(pass.GetRenderTargetSize()));
322  uniforms.mvp = pass.GetOrthographicTransform() *
323  Matrix::MakeScale(GetContentScale()) *
324  Matrix::MakeTranslation({i * 50.0f, j * 50.0f, 0.0f});
325  VS::BindUniformBuffer(pass, host_buffer->EmplaceUniform(uniforms));
326  if (!pass.Draw().ok()) {
327  return false;
328  }
329  }
330  }
331 
332  host_buffer->Reset();
333  return true;
334  };
335  OpenPlaygroundHere(callback);
336 }

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

impeller::testing::TEST_P ( RendererTest  ,
CanRenderPerspectiveCube   
)

Definition at line 176 of file renderer_unittests.cc.

176  {
177  using VS = ColorsVertexShader;
178  using FS = ColorsFragmentShader;
179  auto context = GetContext();
180  ASSERT_TRUE(context);
181  auto desc = PipelineBuilder<VS, FS>::MakeDefaultPipelineDescriptor(*context);
182  ASSERT_TRUE(desc.has_value());
183  desc->SetCullMode(CullMode::kBackFace);
184  desc->SetWindingOrder(WindingOrder::kCounterClockwise);
185  desc->SetSampleCount(SampleCount::kCount4);
186  desc->SetStencilAttachmentDescriptors(std::nullopt);
187  auto pipeline =
188  context->GetPipelineLibrary()->GetPipeline(std::move(desc)).Get();
189  ASSERT_TRUE(pipeline);
190 
191  struct Cube {
192  VS::PerVertexData vertices[8] = {
193  // -Z
194  {{-1, -1, -1}, Color::Red()},
195  {{1, -1, -1}, Color::Yellow()},
196  {{1, 1, -1}, Color::Green()},
197  {{-1, 1, -1}, Color::Blue()},
198  // +Z
199  {{-1, -1, 1}, Color::Green()},
200  {{1, -1, 1}, Color::Blue()},
201  {{1, 1, 1}, Color::Red()},
202  {{-1, 1, 1}, Color::Yellow()},
203  };
204  uint16_t indices[36] = {
205  1, 5, 2, 2, 5, 6, // +X
206  4, 0, 7, 7, 0, 3, // -X
207  4, 5, 0, 0, 5, 1, // +Y
208  3, 2, 7, 7, 2, 6, // -Y
209  5, 4, 6, 6, 4, 7, // +Z
210  0, 1, 3, 3, 1, 2, // -Z
211  };
212  } cube;
213 
214  VertexBuffer vertex_buffer;
215  {
216  auto device_buffer = context->GetResourceAllocator()->CreateBufferWithCopy(
217  reinterpret_cast<uint8_t*>(&cube), sizeof(cube));
218  vertex_buffer.vertex_buffer = {
219  .buffer = device_buffer,
220  .range = Range(offsetof(Cube, vertices), sizeof(Cube::vertices))};
221  vertex_buffer.index_buffer = {
222  .buffer = device_buffer,
223  .range = Range(offsetof(Cube, indices), sizeof(Cube::indices))};
224  vertex_buffer.vertex_count = 36;
225  vertex_buffer.index_type = IndexType::k16bit;
226  }
227 
228  const std::unique_ptr<const Sampler>& sampler =
229  context->GetSamplerLibrary()->GetSampler({});
230  ASSERT_TRUE(sampler);
231 
232  Vector3 euler_angles;
233  auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
234  SinglePassCallback callback = [&](RenderPass& pass) {
235  static Degrees fov_y(60);
236  static Scalar distance = 10;
237 
238  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
239  ImGui::SliderFloat("Field of view", &fov_y.degrees, 0, 180);
240  ImGui::SliderFloat("Camera distance", &distance, 0, 30);
241  ImGui::End();
242 
243  pass.SetCommandLabel("Perspective Cube");
244  pass.SetPipeline(pipeline);
245  pass.SetVertexBuffer(vertex_buffer);
246 
247  VS::UniformBuffer uniforms;
248  Scalar time = GetSecondsElapsed();
249  euler_angles = Vector3(0.19 * time, 0.7 * time, 0.43 * time);
250 
251  uniforms.mvp =
252  Matrix::MakePerspective(fov_y, pass.GetRenderTargetSize(), 0, 10) *
253  Matrix::MakeTranslation({0, 0, distance}) *
254  Matrix::MakeRotationX(Radians(euler_angles.x)) *
255  Matrix::MakeRotationY(Radians(euler_angles.y)) *
256  Matrix::MakeRotationZ(Radians(euler_angles.z));
257  VS::BindUniformBuffer(pass, host_buffer->EmplaceUniform(uniforms));
258 
259  host_buffer->Reset();
260  return pass.Draw().ok();
261  };
262  OpenPlaygroundHere(callback);
263 }

References impeller::Color::Blue(), impeller::BufferView::buffer, impeller::HostBuffer::Create(), impeller::Degrees::degrees, impeller::saturated::distance, impeller::Color::Green(), impeller::VertexBuffer::index_buffer, impeller::VertexBuffer::index_type, 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::Color::Red(), impeller::VertexBuffer::vertex_buffer, impeller::VertexBuffer::vertex_count, impeller::Vector3::x, impeller::Vector3::y, impeller::Color::Yellow(), and impeller::Vector3::z.

◆ TEST_P() [422/456]

impeller::testing::TEST_P ( RendererTest  ,
CanRenderToTexture   
)

Definition at line 338 of file renderer_unittests.cc.

338  {
339  using VS = BoxFadeVertexShader;
340  using FS = BoxFadeFragmentShader;
341  auto context = GetContext();
342  ASSERT_TRUE(context);
343  using BoxPipelineBuilder = PipelineBuilder<VS, FS>;
344  auto pipeline_desc =
345  BoxPipelineBuilder::MakeDefaultPipelineDescriptor(*context);
346  pipeline_desc->SetSampleCount(SampleCount::kCount1);
347  pipeline_desc->ClearDepthAttachment();
348  pipeline_desc->SetStencilPixelFormat(PixelFormat::kS8UInt);
349 
350  ASSERT_TRUE(pipeline_desc.has_value());
351  auto box_pipeline =
352  context->GetPipelineLibrary()->GetPipeline(pipeline_desc).Get();
353  ASSERT_TRUE(box_pipeline);
354  auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
355 
356  VertexBufferBuilder<VS::PerVertexData> vertex_builder;
357  vertex_builder.SetLabel("Box");
358  vertex_builder.AddVertices({
359  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
360  {{800, 100, 0.0}, {1.0, 0.0}}, // 2
361  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
362  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
363  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
364  {{100, 800, 0.0}, {0.0, 1.0}}, // 4
365  });
366  auto vertex_buffer =
367  vertex_builder.CreateVertexBuffer(*context->GetResourceAllocator());
368  ASSERT_TRUE(vertex_buffer);
369 
370  auto bridge = CreateTextureForFixture("bay_bridge.jpg");
371  auto boston = CreateTextureForFixture("boston.jpg");
372  ASSERT_TRUE(bridge && boston);
373  const std::unique_ptr<const Sampler>& sampler =
374  context->GetSamplerLibrary()->GetSampler({});
375  ASSERT_TRUE(sampler);
376 
377  std::shared_ptr<RenderPass> r2t_pass;
378  auto cmd_buffer = context->CreateCommandBuffer();
379  ASSERT_TRUE(cmd_buffer);
380  {
381  ColorAttachment color0;
382  color0.load_action = LoadAction::kClear;
383  color0.store_action = StoreAction::kStore;
384 
385  TextureDescriptor texture_descriptor;
386  ASSERT_NE(pipeline_desc->GetColorAttachmentDescriptor(0u), nullptr);
387  texture_descriptor.format =
388  pipeline_desc->GetColorAttachmentDescriptor(0u)->format;
389  texture_descriptor.storage_mode = StorageMode::kHostVisible;
390  texture_descriptor.size = {400, 400};
391  texture_descriptor.mip_count = 1u;
392  texture_descriptor.usage = TextureUsage::kRenderTarget;
393 
394  color0.texture =
395  context->GetResourceAllocator()->CreateTexture(texture_descriptor);
396 
397  ASSERT_TRUE(color0.IsValid());
398 
399  color0.texture->SetLabel("r2t_target");
400 
401  StencilAttachment stencil0;
402  stencil0.load_action = LoadAction::kClear;
403  stencil0.store_action = StoreAction::kDontCare;
404  TextureDescriptor stencil_texture_desc;
405  stencil_texture_desc.storage_mode = StorageMode::kDeviceTransient;
406  stencil_texture_desc.size = texture_descriptor.size;
407  stencil_texture_desc.format = PixelFormat::kS8UInt;
408  stencil_texture_desc.usage = TextureUsage::kRenderTarget;
409  stencil0.texture =
410  context->GetResourceAllocator()->CreateTexture(stencil_texture_desc);
411 
412  RenderTarget r2t_desc;
413  r2t_desc.SetColorAttachment(color0, 0u);
414  r2t_desc.SetStencilAttachment(stencil0);
415  r2t_pass = cmd_buffer->CreateRenderPass(r2t_desc);
416  ASSERT_TRUE(r2t_pass && r2t_pass->IsValid());
417  }
418 
419  r2t_pass->SetCommandLabel("Box");
420  r2t_pass->SetPipeline(box_pipeline);
421  r2t_pass->SetVertexBuffer(vertex_buffer);
422 
423  FS::FrameInfo frame_info;
424  frame_info.current_time = GetSecondsElapsed();
425  frame_info.cursor_position = GetCursorPosition();
426  frame_info.window_size.x = GetWindowSize().width;
427  frame_info.window_size.y = GetWindowSize().height;
428 
429  FS::BindFrameInfo(*r2t_pass, host_buffer->EmplaceUniform(frame_info));
430  FS::BindContents1(*r2t_pass, boston, sampler);
431  FS::BindContents2(*r2t_pass, bridge, sampler);
432 
433  VS::UniformBuffer uniforms;
434  uniforms.mvp = Matrix::MakeOrthographic(ISize{1024, 768}) *
435  Matrix::MakeTranslation({50.0f, 50.0f, 0.0f});
436  VS::BindUniformBuffer(*r2t_pass, host_buffer->EmplaceUniform(uniforms));
437  ASSERT_TRUE(r2t_pass->Draw().ok());
438  ASSERT_TRUE(r2t_pass->EncodeCommands());
439 }

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

impeller::testing::TEST_P ( RendererTest  ,
CanSepiaToneThenSwizzleWithSubpasses   
)

Definition at line 1489 of file renderer_unittests.cc.

1489  {
1490  // The GLES framebuffer fetch implementation currently does not support this.
1491  // TODO(chinmaygarde): revisit after the GLES framebuffer fetch capabilities
1492  // are clarified.
1493  if (GetParam() == PlaygroundBackend::kOpenGLES) {
1494  GTEST_SKIP_("Not supported on GLES.");
1495  }
1496 
1497  // Define shader types
1498  using TextureVS = TextureVertexShader;
1499  using TextureFS = TextureFragmentShader;
1500 
1501  using SwizzleVS = SepiaVertexShader;
1502  using SwizzleFS = SwizzleFragmentShader;
1503 
1504  using SepiaVS = SepiaVertexShader;
1505  using SepiaFS = SepiaFragmentShader;
1506 
1507  auto context = GetContext();
1508  ASSERT_TRUE(context);
1509 
1510  if (!context->GetCapabilities()->SupportsFramebufferFetch()) {
1511  GTEST_SKIP_(
1512  "This test uses framebuffer fetch and the backend doesn't support it.");
1513  return;
1514  }
1515 
1516  // Create pipelines.
1517  auto texture_pipeline = CreateDefaultPipeline<TextureVS, TextureFS>(context);
1518  auto swizzle_pipeline = CreateDefaultPipeline<SwizzleVS, SwizzleFS>(context);
1519  auto sepia_pipeline = CreateDefaultPipeline<SepiaVS, SepiaFS>(context);
1520 
1521  ASSERT_TRUE(texture_pipeline);
1522  ASSERT_TRUE(swizzle_pipeline);
1523  ASSERT_TRUE(sepia_pipeline);
1524 
1525  // Vertex buffer builders.
1526  VertexBufferBuilder<TextureVS::PerVertexData> texture_vtx_builder;
1527  texture_vtx_builder.AddVertices({
1528  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
1529  {{800, 100, 0.0}, {1.0, 0.0}}, // 2
1530  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
1531  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
1532  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
1533  {{100, 800, 0.0}, {0.0, 1.0}}, // 4
1534  });
1535 
1536  VertexBufferBuilder<SepiaVS::PerVertexData> sepia_vtx_builder;
1537  sepia_vtx_builder.AddVertices({
1538  {{100, 100, 0.0}}, // 1
1539  {{800, 100, 0.0}}, // 2
1540  {{800, 800, 0.0}}, // 3
1541  {{100, 100, 0.0}}, // 1
1542  {{800, 800, 0.0}}, // 3
1543  {{100, 800, 0.0}}, // 4
1544  });
1545 
1546  auto boston = CreateTextureForFixture("boston.jpg");
1547  ASSERT_TRUE(boston);
1548 
1549  const auto& sampler = context->GetSamplerLibrary()->GetSampler({});
1550  ASSERT_TRUE(sampler);
1551 
1552  SinglePassCallback callback = [&](RenderPass& pass) {
1553  auto buffer = HostBuffer::Create(context->GetResourceAllocator());
1554 
1555  // Draw the texture.
1556  {
1557  pass.SetPipeline(texture_pipeline);
1558  pass.SetVertexBuffer(texture_vtx_builder.CreateVertexBuffer(
1559  *context->GetResourceAllocator()));
1560  TextureVS::UniformBuffer uniforms;
1561  uniforms.mvp = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) *
1562  Matrix::MakeScale(GetContentScale());
1563  TextureVS::BindUniformBuffer(pass, buffer->EmplaceUniform(uniforms));
1564  TextureFS::BindTextureContents(pass, boston, sampler);
1565  if (!pass.Draw().ok()) {
1566  return false;
1567  }
1568  }
1569 
1570  // Draw the sepia toner.
1571  {
1572  pass.SetPipeline(sepia_pipeline);
1573  pass.SetVertexBuffer(sepia_vtx_builder.CreateVertexBuffer(
1574  *context->GetResourceAllocator()));
1575  SepiaVS::UniformBuffer uniforms;
1576  uniforms.mvp = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) *
1577  Matrix::MakeScale(GetContentScale());
1578  SepiaVS::BindUniformBuffer(pass, buffer->EmplaceUniform(uniforms));
1579  if (!pass.Draw().ok()) {
1580  return false;
1581  }
1582  }
1583 
1584  // Draw the swizzle.
1585  {
1586  pass.SetPipeline(swizzle_pipeline);
1587  pass.SetVertexBuffer(sepia_vtx_builder.CreateVertexBuffer(
1588  *context->GetResourceAllocator()));
1589  SwizzleVS::UniformBuffer uniforms;
1590  uniforms.mvp = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) *
1591  Matrix::MakeScale(GetContentScale());
1592  SwizzleVS::BindUniformBuffer(pass, buffer->EmplaceUniform(uniforms));
1593  if (!pass.Draw().ok()) {
1594  return false;
1595  }
1596  }
1597 
1598  return true;
1599  };
1600  OpenPlaygroundHere(callback);
1601 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), impeller::HostBuffer::Create(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::CreateVertexBuffer(), impeller::kOpenGLES, impeller::Matrix::MakeOrthographic(), and impeller::Matrix::MakeScale().

◆ TEST_P() [424/456]

impeller::testing::TEST_P ( RendererTest  ,
CanSepiaToneWithSubpasses   
)

Definition at line 1394 of file renderer_unittests.cc.

1394  {
1395  // The GLES framebuffer fetch implementation currently does not support this.
1396  // TODO(chinmaygarde): revisit after the GLES framebuffer fetch capabilities
1397  // are clarified.
1398  if (GetParam() == PlaygroundBackend::kOpenGLES) {
1399  GTEST_SKIP_("Not supported on GLES.");
1400  }
1401 
1402  // Define shader types
1403  using TextureVS = TextureVertexShader;
1404  using TextureFS = TextureFragmentShader;
1405 
1406  using SepiaVS = SepiaVertexShader;
1407  using SepiaFS = SepiaFragmentShader;
1408 
1409  auto context = GetContext();
1410  ASSERT_TRUE(context);
1411 
1412  if (!context->GetCapabilities()->SupportsFramebufferFetch()) {
1413  GTEST_SKIP_(
1414  "This test uses framebuffer fetch and the backend doesn't support it.");
1415  return;
1416  }
1417 
1418  // Create pipelines.
1419  auto texture_pipeline = CreateDefaultPipeline<TextureVS, TextureFS>(context);
1420  auto sepia_pipeline = CreateDefaultPipeline<SepiaVS, SepiaFS>(context);
1421 
1422  ASSERT_TRUE(texture_pipeline);
1423  ASSERT_TRUE(sepia_pipeline);
1424 
1425  // Vertex buffer builders.
1426  VertexBufferBuilder<TextureVS::PerVertexData> texture_vtx_builder;
1427  texture_vtx_builder.AddVertices({
1428  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
1429  {{800, 100, 0.0}, {1.0, 0.0}}, // 2
1430  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
1431  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
1432  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
1433  {{100, 800, 0.0}, {0.0, 1.0}}, // 4
1434  });
1435 
1436  VertexBufferBuilder<SepiaVS::PerVertexData> sepia_vtx_builder;
1437  sepia_vtx_builder.AddVertices({
1438  {{100, 100, 0.0}}, // 1
1439  {{800, 100, 0.0}}, // 2
1440  {{800, 800, 0.0}}, // 3
1441  {{100, 100, 0.0}}, // 1
1442  {{800, 800, 0.0}}, // 3
1443  {{100, 800, 0.0}}, // 4
1444  });
1445 
1446  auto boston = CreateTextureForFixture("boston.jpg");
1447  ASSERT_TRUE(boston);
1448 
1449  const auto& sampler = context->GetSamplerLibrary()->GetSampler({});
1450  ASSERT_TRUE(sampler);
1451 
1452  SinglePassCallback callback = [&](RenderPass& pass) {
1453  auto buffer = HostBuffer::Create(context->GetResourceAllocator());
1454 
1455  // Draw the texture.
1456  {
1457  pass.SetPipeline(texture_pipeline);
1458  pass.SetVertexBuffer(texture_vtx_builder.CreateVertexBuffer(
1459  *context->GetResourceAllocator()));
1460  TextureVS::UniformBuffer uniforms;
1461  uniforms.mvp = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) *
1462  Matrix::MakeScale(GetContentScale());
1463  TextureVS::BindUniformBuffer(pass, buffer->EmplaceUniform(uniforms));
1464  TextureFS::BindTextureContents(pass, boston, sampler);
1465  if (!pass.Draw().ok()) {
1466  return false;
1467  }
1468  }
1469 
1470  // Draw the sepia toner.
1471  {
1472  pass.SetPipeline(sepia_pipeline);
1473  pass.SetVertexBuffer(sepia_vtx_builder.CreateVertexBuffer(
1474  *context->GetResourceAllocator()));
1475  SepiaVS::UniformBuffer uniforms;
1476  uniforms.mvp = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) *
1477  Matrix::MakeScale(GetContentScale());
1478  SepiaVS::BindUniformBuffer(pass, buffer->EmplaceUniform(uniforms));
1479  if (!pass.Draw().ok()) {
1480  return false;
1481  }
1482  }
1483 
1484  return true;
1485  };
1486  OpenPlaygroundHere(callback);
1487 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), impeller::HostBuffer::Create(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::CreateVertexBuffer(), impeller::kOpenGLES, impeller::Matrix::MakeOrthographic(), and impeller::Matrix::MakeScale().

◆ TEST_P() [425/456]

impeller::testing::TEST_P ( RendererTest  ,
DefaultIndexBehavior   
)

Definition at line 1111 of file renderer_unittests.cc.

1111  {
1112  using VS = BoxFadeVertexShader;
1113 
1114  // Do not create any index buffer if no indices were provided.
1115  VertexBufferBuilder<VS::PerVertexData> vertex_builder;
1116  ASSERT_EQ(vertex_builder.GetIndexType(), IndexType::kNone);
1117 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::GetIndexType(), and impeller::kNone.

◆ TEST_P() [426/456]

impeller::testing::TEST_P ( RendererTest  ,
DefaultIndexSize   
)

Definition at line 1101 of file renderer_unittests.cc.

1101  {
1102  using VS = BoxFadeVertexShader;
1103 
1104  // Default to 16bit index buffer size, as this is a reasonable default and
1105  // supported on all backends without extensions.
1106  VertexBufferBuilder<VS::PerVertexData> vertex_builder;
1107  vertex_builder.AppendIndex(0u);
1108  ASSERT_EQ(vertex_builder.GetIndexType(), IndexType::k16bit);
1109 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AppendIndex(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::GetIndexType(), and impeller::k16bit.

◆ TEST_P() [427/456]

impeller::testing::TEST_P ( RendererTest  ,
InactiveUniforms   
)

Definition at line 1054 of file renderer_unittests.cc.

1054  {
1055  using VS = InactiveUniformsVertexShader;
1056  using FS = InactiveUniformsFragmentShader;
1057 
1058  auto context = GetContext();
1059  auto pipeline_descriptor =
1060  PipelineBuilder<VS, FS>::MakeDefaultPipelineDescriptor(*context);
1061  ASSERT_TRUE(pipeline_descriptor.has_value());
1062  pipeline_descriptor->SetSampleCount(SampleCount::kCount4);
1063  pipeline_descriptor->SetStencilAttachmentDescriptors(std::nullopt);
1064  auto pipeline =
1065  context->GetPipelineLibrary()->GetPipeline(pipeline_descriptor).Get();
1066  ASSERT_TRUE(pipeline && pipeline->IsValid());
1067 
1068  auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
1069  SinglePassCallback callback = [&](RenderPass& pass) {
1070  auto size = pass.GetRenderTargetSize();
1071 
1072  pass.SetPipeline(pipeline);
1073  pass.SetCommandLabel("Inactive Uniform");
1074 
1075  VertexBufferBuilder<VS::PerVertexData> builder;
1076  builder.AddVertices({{Point()},
1077  {Point(0, size.height)},
1078  {Point(size.width, 0)},
1079  {Point(size.width, 0)},
1080  {Point(0, size.height)},
1081  {Point(size.width, size.height)}});
1082  pass.SetVertexBuffer(builder.CreateVertexBuffer(*host_buffer));
1083 
1084  VS::FrameInfo frame_info;
1085  EXPECT_EQ(pass.GetOrthographicTransform(), Matrix::MakeOrthographic(size));
1086  frame_info.mvp =
1087  pass.GetOrthographicTransform() * Matrix::MakeScale(GetContentScale());
1088  VS::BindFrameInfo(pass, host_buffer->EmplaceUniform(frame_info));
1089 
1090  FS::FragInfo fs_uniform = {.unused_color = Color::Red(),
1091  .color = Color::Green()};
1092  FS::BindFragInfo(pass, host_buffer->EmplaceUniform(fs_uniform));
1093 
1094  pass.Draw().ok();
1095  host_buffer->Reset();
1096  return true;
1097  };
1098  OpenPlaygroundHere(callback);
1099 }

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

impeller::testing::TEST_P ( RendererTest  ,
Planet   
)

Definition at line 931 of file renderer_unittests.cc.

931  {
932  using VS = PlanetVertexShader;
933  using FS = PlanetFragmentShader;
934 
935  auto context = GetContext();
936  auto pipeline_descriptor =
937  PipelineBuilder<VS, FS>::MakeDefaultPipelineDescriptor(*context);
938  ASSERT_TRUE(pipeline_descriptor.has_value());
939  pipeline_descriptor->SetSampleCount(SampleCount::kCount4);
940  pipeline_descriptor->SetStencilAttachmentDescriptors(std::nullopt);
941  auto pipeline =
942  context->GetPipelineLibrary()->GetPipeline(pipeline_descriptor).Get();
943  ASSERT_TRUE(pipeline && pipeline->IsValid());
944 
945  auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
946 
947  SinglePassCallback callback = [&](RenderPass& pass) {
948  static Scalar speed = 0.1;
949  static Scalar planet_size = 550.0;
950  static bool show_normals = false;
951  static bool show_noise = false;
952  static Scalar seed_value = 42.0;
953 
954  auto size = pass.GetRenderTargetSize();
955 
956  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
957  ImGui::SliderFloat("Speed", &speed, 0.0, 10.0);
958  ImGui::SliderFloat("Planet Size", &planet_size, 0.1, 1000);
959  ImGui::Checkbox("Show Normals", &show_normals);
960  ImGui::Checkbox("Show Noise", &show_noise);
961  ImGui::InputFloat("Seed Value", &seed_value);
962  ImGui::End();
963 
964  pass.SetPipeline(pipeline);
965  pass.SetCommandLabel("Planet scene");
966  VertexBufferBuilder<VS::PerVertexData> builder;
967  builder.AddVertices({{Point()},
968  {Point(0, size.height)},
969  {Point(size.width, 0)},
970  {Point(size.width, 0)},
971  {Point(0, size.height)},
972  {Point(size.width, size.height)}});
973  pass.SetVertexBuffer(builder.CreateVertexBuffer(*host_buffer));
974 
975  VS::FrameInfo frame_info;
976  EXPECT_EQ(pass.GetOrthographicTransform(), Matrix::MakeOrthographic(size));
977  frame_info.mvp = pass.GetOrthographicTransform();
978  VS::BindFrameInfo(pass, host_buffer->EmplaceUniform(frame_info));
979 
980  FS::FragInfo fs_uniform;
981  fs_uniform.resolution = Point(size);
982  fs_uniform.time = GetSecondsElapsed();
983  fs_uniform.speed = speed;
984  fs_uniform.planet_size = planet_size;
985  fs_uniform.show_normals = show_normals ? 1.0 : 0.0;
986  fs_uniform.show_noise = show_noise ? 1.0 : 0.0;
987  fs_uniform.seed_value = seed_value;
988  FS::BindFragInfo(pass, host_buffer->EmplaceUniform(fs_uniform));
989 
990  pass.Draw().ok();
991  host_buffer->Reset();
992  return true;
993  };
994  OpenPlaygroundHere(callback);
995 }

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

impeller::testing::TEST_P ( RendererTest  ,
RenderTargetCreateOffscreenMSAASetsDefaultDepthStencilFormat   
)

Definition at line 1361 of file renderer_unittests.cc.

1362  {
1363  auto context = GetContext();
1364  auto render_target_cache = std::make_shared<RenderTargetAllocator>(
1365  GetContext()->GetResourceAllocator());
1366 
1367  RenderTarget render_target = render_target_cache->CreateOffscreenMSAA(
1368  *context, {100, 100}, /*mip_count=*/1);
1369  EXPECT_EQ(render_target.GetDepthAttachment()
1370  ->texture->GetTextureDescriptor()
1371  .format,
1372  GetContext()->GetCapabilities()->GetDefaultDepthStencilFormat());
1373 }

References impeller::RenderTarget::GetDepthAttachment().

◆ TEST_P() [430/456]

impeller::testing::TEST_P ( RendererTest  ,
StencilMask   
)

Definition at line 1189 of file renderer_unittests.cc.

1189  {
1190  using VS = BoxFadeVertexShader;
1191  using FS = BoxFadeFragmentShader;
1192  auto context = GetContext();
1193  ASSERT_TRUE(context);
1194  using BoxFadePipelineBuilder = PipelineBuilder<VS, FS>;
1195  auto desc = BoxFadePipelineBuilder::MakeDefaultPipelineDescriptor(*context);
1196  ASSERT_TRUE(desc.has_value());
1197 
1198  // Vertex buffer.
1199  VertexBufferBuilder<VS::PerVertexData> vertex_builder;
1200  vertex_builder.SetLabel("Box");
1201  vertex_builder.AddVertices({
1202  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
1203  {{800, 100, 0.0}, {1.0, 0.0}}, // 2
1204  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
1205  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
1206  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
1207  {{100, 800, 0.0}, {0.0, 1.0}}, // 4
1208  });
1209  auto vertex_buffer =
1210  vertex_builder.CreateVertexBuffer(*context->GetResourceAllocator());
1211  ASSERT_TRUE(vertex_buffer);
1212 
1213  desc->SetSampleCount(SampleCount::kCount4);
1214  desc->SetStencilAttachmentDescriptors(std::nullopt);
1215 
1216  auto bridge = CreateTextureForFixture("bay_bridge.jpg");
1217  auto boston = CreateTextureForFixture("boston.jpg");
1218  ASSERT_TRUE(bridge && boston);
1219  const std::unique_ptr<const Sampler>& sampler =
1220  context->GetSamplerLibrary()->GetSampler({});
1221  ASSERT_TRUE(sampler);
1222 
1223  static bool mirror = false;
1224  static int stencil_reference_write = 0xFF;
1225  static int stencil_reference_read = 0x1;
1226  std::vector<uint8_t> stencil_contents;
1227  static int last_stencil_contents_reference_value = 0;
1228  static int current_front_compare =
1229  CompareFunctionUI().IndexOf(CompareFunction::kLessEqual);
1230  static int current_back_compare =
1231  CompareFunctionUI().IndexOf(CompareFunction::kLessEqual);
1232 
1233  auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
1234  Renderer::RenderCallback callback = [&](RenderTarget& render_target) {
1235  auto buffer = context->CreateCommandBuffer();
1236  if (!buffer) {
1237  return false;
1238  }
1239  buffer->SetLabel("Playground Command Buffer");
1240 
1241  {
1242  // Configure the stencil attachment for the test.
1243  RenderTarget::AttachmentConfig stencil_config;
1244  stencil_config.load_action = LoadAction::kLoad;
1245  stencil_config.store_action = StoreAction::kDontCare;
1246  stencil_config.storage_mode = StorageMode::kHostVisible;
1247  render_target.SetupDepthStencilAttachments(
1248  *context, *context->GetResourceAllocator(),
1249  render_target.GetRenderTargetSize(), true, "stencil", stencil_config);
1250  // Fill the stencil buffer with an checkerboard pattern.
1251  const auto target_width = render_target.GetRenderTargetSize().width;
1252  const auto target_height = render_target.GetRenderTargetSize().height;
1253  const size_t target_size = target_width * target_height;
1254  if (stencil_contents.size() != target_size ||
1255  last_stencil_contents_reference_value != stencil_reference_write) {
1256  stencil_contents.resize(target_size);
1257  last_stencil_contents_reference_value = stencil_reference_write;
1258  for (int y = 0; y < target_height; y++) {
1259  for (int x = 0; x < target_width; x++) {
1260  const auto index = y * target_width + x;
1261  const auto kCheckSize = 64;
1262  const auto value =
1263  (((y / kCheckSize) + (x / kCheckSize)) % 2 == 0) *
1264  stencil_reference_write;
1265  stencil_contents[index] = value;
1266  }
1267  }
1268  }
1269  if (!render_target.GetStencilAttachment()->texture->SetContents(
1270  stencil_contents.data(), stencil_contents.size(), 0, false)) {
1271  VALIDATION_LOG << "Could not upload stencil contents to device memory";
1272  return false;
1273  }
1274  auto pass = buffer->CreateRenderPass(render_target);
1275  if (!pass) {
1276  return false;
1277  }
1278  pass->SetLabel("Stencil Buffer");
1279  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
1280  ImGui::SliderInt("Stencil Write Value", &stencil_reference_write, 0,
1281  0xFF);
1282  ImGui::SliderInt("Stencil Compare Value", &stencil_reference_read, 0,
1283  0xFF);
1284  ImGui::Checkbox("Back face mode", &mirror);
1285  ImGui::ListBox("Front face compare function", &current_front_compare,
1286  CompareFunctionUI().labels(), CompareFunctionUI().size());
1287  ImGui::ListBox("Back face compare function", &current_back_compare,
1288  CompareFunctionUI().labels(), CompareFunctionUI().size());
1289  ImGui::End();
1290 
1291  StencilAttachmentDescriptor front;
1292  front.stencil_compare =
1293  CompareFunctionUI().FunctionOf(current_front_compare);
1294  StencilAttachmentDescriptor back;
1295  back.stencil_compare =
1296  CompareFunctionUI().FunctionOf(current_back_compare);
1297  desc->SetStencilAttachmentDescriptors(front, back);
1298  auto pipeline = context->GetPipelineLibrary()->GetPipeline(desc).Get();
1299 
1300  assert(pipeline && pipeline->IsValid());
1301 
1302  pass->SetCommandLabel("Box");
1303  pass->SetPipeline(pipeline);
1304  pass->SetStencilReference(stencil_reference_read);
1305  pass->SetVertexBuffer(vertex_buffer);
1306 
1307  VS::UniformBuffer uniforms;
1308  EXPECT_EQ(pass->GetOrthographicTransform(),
1309  Matrix::MakeOrthographic(pass->GetRenderTargetSize()));
1310  uniforms.mvp = pass->GetOrthographicTransform() *
1311  Matrix::MakeScale(GetContentScale());
1312  if (mirror) {
1313  uniforms.mvp = Matrix::MakeScale(Vector2(-1, 1)) * uniforms.mvp;
1314  }
1315  VS::BindUniformBuffer(*pass, host_buffer->EmplaceUniform(uniforms));
1316 
1317  FS::FrameInfo frame_info;
1318  frame_info.current_time = GetSecondsElapsed();
1319  frame_info.cursor_position = GetCursorPosition();
1320  frame_info.window_size.x = GetWindowSize().width;
1321  frame_info.window_size.y = GetWindowSize().height;
1322 
1323  FS::BindFrameInfo(*pass, host_buffer->EmplaceUniform(frame_info));
1324  FS::BindContents1(*pass, boston, sampler);
1325  FS::BindContents2(*pass, bridge, sampler);
1326  if (!pass->Draw().ok()) {
1327  return false;
1328  }
1329  pass->EncodeCommands();
1330  }
1331 
1332  if (!context->GetCommandQueue()->Submit({buffer}).ok()) {
1333  return false;
1334  }
1335  host_buffer->Reset();
1336  return true;
1337  };
1338  OpenPlaygroundHere(callback);
1339 }

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, and VALIDATION_LOG.

◆ TEST_P() [431/456]

impeller::testing::TEST_P ( RendererTest  ,
TheImpeller   
)

Definition at line 869 of file renderer_unittests.cc.

869  {
870  using VS = ImpellerVertexShader;
871  using FS = ImpellerFragmentShader;
872 
873  auto context = GetContext();
874  auto pipeline_descriptor =
875  PipelineBuilder<VS, FS>::MakeDefaultPipelineDescriptor(*context);
876  ASSERT_TRUE(pipeline_descriptor.has_value());
877  pipeline_descriptor->SetSampleCount(SampleCount::kCount4);
878  pipeline_descriptor->SetStencilAttachmentDescriptors(std::nullopt);
879  auto pipeline =
880  context->GetPipelineLibrary()->GetPipeline(pipeline_descriptor).Get();
881  ASSERT_TRUE(pipeline && pipeline->IsValid());
882 
883  auto blue_noise = CreateTextureForFixture("blue_noise.png");
884  SamplerDescriptor noise_sampler_desc;
885  noise_sampler_desc.width_address_mode = SamplerAddressMode::kRepeat;
886  noise_sampler_desc.height_address_mode = SamplerAddressMode::kRepeat;
887  const std::unique_ptr<const Sampler>& noise_sampler =
888  context->GetSamplerLibrary()->GetSampler(noise_sampler_desc);
889 
890  auto cube_map = CreateTextureCubeForFixture(
891  {"table_mountain_px.png", "table_mountain_nx.png",
892  "table_mountain_py.png", "table_mountain_ny.png",
893  "table_mountain_pz.png", "table_mountain_nz.png"});
894  const std::unique_ptr<const Sampler>& cube_map_sampler =
895  context->GetSamplerLibrary()->GetSampler({});
896  auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
897 
898  SinglePassCallback callback = [&](RenderPass& pass) {
899  auto size = pass.GetRenderTargetSize();
900 
901  pass.SetPipeline(pipeline);
902  pass.SetCommandLabel("Impeller SDF scene");
903  VertexBufferBuilder<VS::PerVertexData> builder;
904  builder.AddVertices({{Point()},
905  {Point(0, size.height)},
906  {Point(size.width, 0)},
907  {Point(size.width, 0)},
908  {Point(0, size.height)},
909  {Point(size.width, size.height)}});
910  pass.SetVertexBuffer(builder.CreateVertexBuffer(*host_buffer));
911 
912  VS::FrameInfo frame_info;
913  EXPECT_EQ(pass.GetOrthographicTransform(), Matrix::MakeOrthographic(size));
914  frame_info.mvp = pass.GetOrthographicTransform();
915  VS::BindFrameInfo(pass, host_buffer->EmplaceUniform(frame_info));
916 
917  FS::FragInfo fs_uniform;
918  fs_uniform.texture_size = Point(size);
919  fs_uniform.time = GetSecondsElapsed();
920  FS::BindFragInfo(pass, host_buffer->EmplaceUniform(fs_uniform));
921  FS::BindBlueNoise(pass, blue_noise, noise_sampler);
922  FS::BindCubeMap(pass, cube_map, cube_map_sampler);
923 
924  pass.Draw().ok();
925  host_buffer->Reset();
926  return true;
927  };
928  OpenPlaygroundHere(callback);
929 }

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

impeller::testing::TEST_P ( RendererTest  ,
VertexBufferBuilder   
)

Definition at line 1119 of file renderer_unittests.cc.

1119  {
1120  // Does not create index buffer if one is provided.
1121  using VS = BoxFadeVertexShader;
1122  VertexBufferBuilder<VS::PerVertexData> vertex_builder;
1123  vertex_builder.SetLabel("Box");
1124  vertex_builder.AddVertices({
1125  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
1126  {{800, 100, 0.0}, {1.0, 0.0}}, // 2
1127  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
1128  {{100, 800, 0.0}, {0.0, 1.0}}, // 4
1129  });
1130  vertex_builder.AppendIndex(0);
1131  vertex_builder.AppendIndex(1);
1132  vertex_builder.AppendIndex(2);
1133  vertex_builder.AppendIndex(1);
1134  vertex_builder.AppendIndex(2);
1135  vertex_builder.AppendIndex(3);
1136 
1137  ASSERT_EQ(vertex_builder.GetIndexCount(), 6u);
1138  ASSERT_EQ(vertex_builder.GetVertexCount(), 4u);
1139 }

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

impeller::testing::TEST_P ( RenderTargetCacheTest  ,
CachedTextureGetsNewAttachmentConfig   
)

Definition at line 90 of file render_target_cache_unittests.cc.

90  {
91  auto render_target_cache =
92  RenderTargetCache(GetContext()->GetResourceAllocator());
93 
94  render_target_cache.Start();
95  RenderTarget::AttachmentConfig color_attachment_config =
96  RenderTarget::kDefaultColorAttachmentConfig;
97  RenderTarget target1 = render_target_cache.CreateOffscreen(
98  *GetContext(), {100, 100}, 1, "Offscreen1", color_attachment_config);
99  render_target_cache.End();
100 
101  render_target_cache.Start();
102  color_attachment_config.clear_color = Color::Red();
103  RenderTarget target2 = render_target_cache.CreateOffscreen(
104  *GetContext(), {100, 100}, 1, "Offscreen2", color_attachment_config);
105  render_target_cache.End();
106 
107  auto color1 = target1.GetColorAttachments().find(0)->second;
108  auto color2 = target2.GetColorAttachments().find(0)->second;
109  // The second color attachment should reuse the first attachment's texture
110  // but with attributes from the second AttachmentConfig.
111  EXPECT_EQ(color2.texture, color1.texture);
112  EXPECT_EQ(color2.clear_color, Color::Red());
113 }

References impeller::RenderTarget::AttachmentConfig::clear_color, impeller::RenderTarget::GetColorAttachments(), impeller::RenderTarget::kDefaultColorAttachmentConfig, and impeller::Color::Red().

◆ TEST_P() [434/456]

impeller::testing::TEST_P ( RenderTargetCacheTest  ,
CachesUsedTexturesAcrossFrames   
)

Definition at line 51 of file render_target_cache_unittests.cc.

51  {
52  auto render_target_cache =
53  RenderTargetCache(GetContext()->GetResourceAllocator());
54 
55  render_target_cache.Start();
56  // Create two render targets of the same exact size/shape. Both should be
57  // marked as used this frame, so the cached data set will contain two.
58  render_target_cache.CreateOffscreen(*GetContext(), {100, 100}, 1);
59  render_target_cache.CreateOffscreen(*GetContext(), {100, 100}, 1);
60 
61  EXPECT_EQ(render_target_cache.CachedTextureCount(), 2u);
62 
63  render_target_cache.End();
64  render_target_cache.Start();
65 
66  // Next frame, only create one texture. The set will still contain two,
67  // but one will be removed at the end of the frame.
68  render_target_cache.CreateOffscreen(*GetContext(), {100, 100}, 1);
69  EXPECT_EQ(render_target_cache.CachedTextureCount(), 2u);
70 
71  render_target_cache.End();
72  EXPECT_EQ(render_target_cache.CachedTextureCount(), 1u);
73 }

◆ TEST_P() [435/456]

impeller::testing::TEST_P ( RenderTargetCacheTest  ,
CreateWithEmptySize   
)

Definition at line 115 of file render_target_cache_unittests.cc.

115  {
116  auto render_target_cache =
117  RenderTargetCache(GetContext()->GetResourceAllocator());
118 
119  render_target_cache.Start();
120  RenderTarget empty_target =
121  render_target_cache.CreateOffscreen(*GetContext(), {100, 0}, 1);
122  RenderTarget empty_target_msaa =
123  render_target_cache.CreateOffscreenMSAA(*GetContext(), {0, 0}, 1);
124  render_target_cache.End();
125 
126  {
127  ScopedValidationDisable disable_validation;
128  EXPECT_FALSE(empty_target.IsValid());
129  EXPECT_FALSE(empty_target_msaa.IsValid());
130  }
131 }

References impeller::RenderTarget::IsValid().

◆ TEST_P() [436/456]

impeller::testing::TEST_P ( RenderTargetCacheTest  ,
DoesNotPersistFailedAllocations   
)

Definition at line 75 of file render_target_cache_unittests.cc.

75  {
76  ScopedValidationDisable disable;
77  auto allocator = std::make_shared<TestAllocator>();
78  auto render_target_cache = RenderTargetCache(allocator);
79 
80  render_target_cache.Start();
81  allocator->should_fail = true;
82 
83  auto render_target =
84  render_target_cache.CreateOffscreen(*GetContext(), {100, 100}, 1);
85 
86  EXPECT_FALSE(render_target.IsValid());
87  EXPECT_EQ(render_target_cache.CachedTextureCount(), 0u);
88 }

◆ TEST_P() [437/456]

impeller::testing::TEST_P ( RuntimeStageTest  ,
CanCreatePipelineFromRuntimeStage   
)

Definition at line 314 of file runtime_stage_unittests.cc.

314  {
315  auto stages = OpenAssetAsRuntimeStage("ink_sparkle.frag.iplr");
316  auto stage = stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
317 
318  ASSERT_TRUE(stage);
319  ASSERT_NE(stage, nullptr);
320  ASSERT_TRUE(RegisterStage(*stage));
321  auto library = GetContext()->GetShaderLibrary();
322  using VS = RuntimeEffectVertexShader;
323  PipelineDescriptor desc;
324  desc.SetLabel("Runtime Stage InkSparkle");
325  desc.AddStageEntrypoint(
326  library->GetFunction(VS::kEntrypointName, ShaderStage::kVertex));
327  desc.AddStageEntrypoint(
328  library->GetFunction(stage->GetEntrypoint(), ShaderStage::kFragment));
329  auto vertex_descriptor = std::make_shared<VertexDescriptor>();
330  vertex_descriptor->SetStageInputs(VS::kAllShaderStageInputs,
331  VS::kInterleavedBufferLayout);
332 
333  std::array<DescriptorSetLayout, 2> descriptor_set_layouts = {
334  VS::kDescriptorSetLayouts[0],
335  DescriptorSetLayout{
336  .binding = 64u,
337  .descriptor_type = DescriptorType::kUniformBuffer,
338  .shader_stage = ShaderStage::kFragment,
339  },
340  };
341  vertex_descriptor->RegisterDescriptorSetLayouts(descriptor_set_layouts);
342 
343  desc.SetVertexDescriptor(std::move(vertex_descriptor));
344  ColorAttachmentDescriptor color0;
345  color0.format = GetContext()->GetCapabilities()->GetDefaultColorFormat();
346  StencilAttachmentDescriptor stencil0;
347  stencil0.stencil_compare = CompareFunction::kEqual;
348  desc.SetColorAttachmentDescriptor(0u, color0);
349  desc.SetStencilAttachmentDescriptors(stencil0);
350  const auto stencil_fmt =
351  GetContext()->GetCapabilities()->GetDefaultStencilFormat();
352  desc.SetStencilPixelFormat(stencil_fmt);
353  auto pipeline = GetContext()->GetPipelineLibrary()->GetPipeline(desc).Get();
354  ASSERT_NE(pipeline, nullptr);
355 }

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

impeller::testing::TEST_P ( RuntimeStageTest  ,
CanReadUniforms   
)

Definition at line 55 of file runtime_stage_unittests.cc.

55  {
56  const std::shared_ptr<fml::Mapping> fixture =
57  flutter::testing::OpenFixtureAsMapping("ink_sparkle.frag.iplr");
58  ASSERT_TRUE(fixture);
59  ASSERT_GT(fixture->GetSize(), 0u);
60  auto stages = RuntimeStage::DecodeRuntimeStages(fixture);
61  auto stage = stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
62 
63  ASSERT_TRUE(stage->IsValid());
64  switch (GetBackend()) {
65  case PlaygroundBackend::kMetal:
66  [[fallthrough]];
67  case PlaygroundBackend::kOpenGLES: {
68  ASSERT_EQ(stage->GetUniforms().size(), 17u);
69  {
70  auto uni = stage->GetUniform("u_color");
71  ASSERT_NE(uni, nullptr);
72  EXPECT_EQ(uni->dimensions.rows, 4u);
73  EXPECT_EQ(uni->dimensions.cols, 1u);
74  EXPECT_EQ(uni->location, 0u);
75  EXPECT_EQ(uni->type, RuntimeUniformType::kFloat);
76  }
77  {
78  auto uni = stage->GetUniform("u_alpha");
79  ASSERT_NE(uni, nullptr);
80  EXPECT_EQ(uni->dimensions.rows, 1u);
81  EXPECT_EQ(uni->dimensions.cols, 1u);
82  EXPECT_EQ(uni->location, 1u);
83  EXPECT_EQ(uni->type, RuntimeUniformType::kFloat);
84  }
85  {
86  auto uni = stage->GetUniform("u_sparkle_color");
87  ASSERT_NE(uni, nullptr);
88  EXPECT_EQ(uni->dimensions.rows, 4u);
89  EXPECT_EQ(uni->dimensions.cols, 1u);
90  EXPECT_EQ(uni->location, 2u);
91  EXPECT_EQ(uni->type, RuntimeUniformType::kFloat);
92  }
93  {
94  auto uni = stage->GetUniform("u_sparkle_alpha");
95  ASSERT_NE(uni, nullptr);
96  EXPECT_EQ(uni->dimensions.rows, 1u);
97  EXPECT_EQ(uni->dimensions.cols, 1u);
98  EXPECT_EQ(uni->location, 3u);
99  EXPECT_EQ(uni->type, RuntimeUniformType::kFloat);
100  }
101  {
102  auto uni = stage->GetUniform("u_blur");
103  ASSERT_NE(uni, nullptr);
104  EXPECT_EQ(uni->dimensions.rows, 1u);
105  EXPECT_EQ(uni->dimensions.cols, 1u);
106  EXPECT_EQ(uni->location, 4u);
107  EXPECT_EQ(uni->type, RuntimeUniformType::kFloat);
108  }
109  {
110  auto uni = stage->GetUniform("u_radius_scale");
111  ASSERT_NE(uni, nullptr);
112  EXPECT_EQ(uni->dimensions.rows, 1u);
113  EXPECT_EQ(uni->dimensions.cols, 1u);
114  EXPECT_EQ(uni->location, 6u);
115  EXPECT_EQ(uni->type, RuntimeUniformType::kFloat);
116  }
117  {
118  auto uni = stage->GetUniform("u_max_radius");
119  ASSERT_NE(uni, nullptr);
120  EXPECT_EQ(uni->dimensions.rows, 1u);
121  EXPECT_EQ(uni->dimensions.cols, 1u);
122  EXPECT_EQ(uni->location, 7u);
123  EXPECT_EQ(uni->type, RuntimeUniformType::kFloat);
124  }
125  {
126  auto uni = stage->GetUniform("u_resolution_scale");
127  ASSERT_NE(uni, nullptr);
128  EXPECT_EQ(uni->dimensions.rows, 2u);
129  EXPECT_EQ(uni->dimensions.cols, 1u);
130  EXPECT_EQ(uni->location, 8u);
131  EXPECT_EQ(uni->type, RuntimeUniformType::kFloat);
132  }
133  {
134  auto uni = stage->GetUniform("u_noise_scale");
135  ASSERT_NE(uni, nullptr);
136  EXPECT_EQ(uni->dimensions.rows, 2u);
137  EXPECT_EQ(uni->dimensions.cols, 1u);
138  EXPECT_EQ(uni->location, 9u);
139  EXPECT_EQ(uni->type, RuntimeUniformType::kFloat);
140  }
141  {
142  auto uni = stage->GetUniform("u_noise_phase");
143  ASSERT_NE(uni, nullptr);
144  EXPECT_EQ(uni->dimensions.rows, 1u);
145  EXPECT_EQ(uni->dimensions.cols, 1u);
146  EXPECT_EQ(uni->location, 10u);
147  EXPECT_EQ(uni->type, RuntimeUniformType::kFloat);
148  }
149 
150  {
151  auto uni = stage->GetUniform("u_circle1");
152  ASSERT_NE(uni, nullptr);
153  EXPECT_EQ(uni->dimensions.rows, 2u);
154  EXPECT_EQ(uni->dimensions.cols, 1u);
155  EXPECT_EQ(uni->location, 11u);
156  EXPECT_EQ(uni->type, RuntimeUniformType::kFloat);
157  }
158  {
159  auto uni = stage->GetUniform("u_circle2");
160  ASSERT_NE(uni, nullptr);
161  EXPECT_EQ(uni->dimensions.rows, 2u);
162  EXPECT_EQ(uni->dimensions.cols, 1u);
163  EXPECT_EQ(uni->location, 12u);
164  EXPECT_EQ(uni->type, RuntimeUniformType::kFloat);
165  }
166  {
167  auto uni = stage->GetUniform("u_circle3");
168  ASSERT_NE(uni, nullptr);
169  EXPECT_EQ(uni->dimensions.rows, 2u);
170  EXPECT_EQ(uni->dimensions.cols, 1u);
171  EXPECT_EQ(uni->location, 13u);
172  EXPECT_EQ(uni->type, RuntimeUniformType::kFloat);
173  }
174  {
175  auto uni = stage->GetUniform("u_rotation1");
176  ASSERT_NE(uni, nullptr);
177  EXPECT_EQ(uni->dimensions.rows, 2u);
178  EXPECT_EQ(uni->dimensions.cols, 1u);
179  EXPECT_EQ(uni->location, 14u);
180  EXPECT_EQ(uni->type, RuntimeUniformType::kFloat);
181  }
182  {
183  auto uni = stage->GetUniform("u_rotation2");
184  ASSERT_NE(uni, nullptr);
185  EXPECT_EQ(uni->dimensions.rows, 2u);
186  EXPECT_EQ(uni->dimensions.cols, 1u);
187  EXPECT_EQ(uni->location, 15u);
188  EXPECT_EQ(uni->type, RuntimeUniformType::kFloat);
189  }
190  {
191  auto uni = stage->GetUniform("u_rotation3");
192  ASSERT_NE(uni, nullptr);
193  EXPECT_EQ(uni->dimensions.rows, 2u);
194  EXPECT_EQ(uni->dimensions.cols, 1u);
195  EXPECT_EQ(uni->location, 16u);
196  EXPECT_EQ(uni->type, RuntimeUniformType::kFloat);
197  }
198  break;
199  }
200  case PlaygroundBackend::kVulkan: {
201  EXPECT_EQ(stage->GetUniforms().size(), 1u);
202  auto uni = stage->GetUniform(RuntimeStage::kVulkanUBOName);
203  ASSERT_TRUE(uni);
204  EXPECT_EQ(uni->type, RuntimeUniformType::kStruct);
205  EXPECT_EQ(uni->struct_float_count, 32u);
206 
207  // There are 36 4 byte chunks in the UBO: 32 for the 32 floats, and 4 for
208  // padding. Initialize a vector as if they'll all be floats, then manually
209  // set the few padding bytes. If the shader changes, the padding locations
210  // will change as well. For example, if `u_alpha` was moved to the end,
211  // three bytes of padding could potentially be dropped - or if some of the
212  // scalar floats were changed to vec2 or vec4s, or if any vec3s are
213  // introduced.
214  // This means 36 * 4 = 144 bytes total.
215 
216  EXPECT_EQ(uni->GetSize(), 144u);
217  std::vector<uint8_t> layout(uni->GetSize() / sizeof(float), 1);
218  layout[5] = 0;
219  layout[6] = 0;
220  layout[7] = 0;
221  layout[23] = 0;
222 
223  EXPECT_THAT(uni->struct_layout, ::testing::ElementsAreArray(layout));
224  break;
225  }
226  }
227 }

References impeller::RuntimeStage::DecodeRuntimeStages(), impeller::kFloat, impeller::kMetal, impeller::kOpenGLES, impeller::kStruct, impeller::kVulkan, impeller::RuntimeStage::kVulkanUBOName, and impeller::PlaygroundBackendToRuntimeStageBackend().

◆ TEST_P() [439/456]

impeller::testing::TEST_P ( RuntimeStageTest  ,
CanReadUniformsSamplerAfterUBO   
)

Definition at line 254 of file runtime_stage_unittests.cc.

254  {
255  if (GetBackend() != PlaygroundBackend::kVulkan) {
256  GTEST_SKIP() << "Test only relevant for Vulkan";
257  }
258  const std::shared_ptr<fml::Mapping> fixture =
259  flutter::testing::OpenFixtureAsMapping(
260  "uniforms_and_sampler_2.frag.iplr");
261  ASSERT_TRUE(fixture);
262  ASSERT_GT(fixture->GetSize(), 0u);
263  auto stages = RuntimeStage::DecodeRuntimeStages(fixture);
264  auto stage = stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
265 
266  EXPECT_EQ(stage->GetUniforms().size(), 2u);
267  auto uni = stage->GetUniform(RuntimeStage::kVulkanUBOName);
268  ASSERT_TRUE(uni);
269  // Struct must be offset at 45.
270  EXPECT_EQ(uni->type, RuntimeUniformType::kStruct);
271  EXPECT_EQ(uni->binding, 64u);
272  // Sampler should be offset at 64 but due to current bug
273  // has offset of 0, the correct offset is computed at runtime.
274  auto sampler_uniform = stage->GetUniform("u_texture");
275  EXPECT_EQ(sampler_uniform->type, RuntimeUniformType::kSampledImage);
276  EXPECT_EQ(sampler_uniform->binding, 65u);
277 }

References impeller::RuntimeStage::DecodeRuntimeStages(), impeller::kSampledImage, impeller::kStruct, impeller::kVulkan, impeller::RuntimeStage::kVulkanUBOName, and impeller::PlaygroundBackendToRuntimeStageBackend().

◆ TEST_P() [440/456]

impeller::testing::TEST_P ( RuntimeStageTest  ,
CanReadUniformsSamplerBeforeUBO   
)

Definition at line 229 of file runtime_stage_unittests.cc.

229  {
230  if (GetBackend() != PlaygroundBackend::kVulkan) {
231  GTEST_SKIP() << "Test only relevant for Vulkan";
232  }
233  const std::shared_ptr<fml::Mapping> fixture =
234  flutter::testing::OpenFixtureAsMapping(
235  "uniforms_and_sampler_1.frag.iplr");
236  ASSERT_TRUE(fixture);
237  ASSERT_GT(fixture->GetSize(), 0u);
238  auto stages = RuntimeStage::DecodeRuntimeStages(fixture);
239  auto stage = stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
240 
241  EXPECT_EQ(stage->GetUniforms().size(), 2u);
242  auto uni = stage->GetUniform(RuntimeStage::kVulkanUBOName);
243  ASSERT_TRUE(uni);
244  // Struct must be offset at 65.
245  EXPECT_EQ(uni->type, RuntimeUniformType::kStruct);
246  EXPECT_EQ(uni->binding, 65u);
247  // Sampler should be offset at 64 but due to current bug
248  // has offset of 0, the correct offset is computed at runtime.
249  auto sampler_uniform = stage->GetUniform("u_texture");
250  EXPECT_EQ(sampler_uniform->type, RuntimeUniformType::kSampledImage);
251  EXPECT_EQ(sampler_uniform->binding, 64u);
252 }

References impeller::RuntimeStage::DecodeRuntimeStages(), impeller::kSampledImage, impeller::kStruct, impeller::kVulkan, impeller::RuntimeStage::kVulkanUBOName, and impeller::PlaygroundBackendToRuntimeStageBackend().

◆ TEST_P() [441/456]

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

impeller::testing::TEST_P ( RuntimeStageTest  ,
CanRegisterStage   
)

Definition at line 279 of file runtime_stage_unittests.cc.

279  {
280  const std::shared_ptr<fml::Mapping> fixture =
281  flutter::testing::OpenFixtureAsMapping("ink_sparkle.frag.iplr");
282  ASSERT_TRUE(fixture);
283  ASSERT_GT(fixture->GetSize(), 0u);
284  auto stages = RuntimeStage::DecodeRuntimeStages(fixture);
285  auto stage = stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
286  ASSERT_TRUE(stage->IsValid());
287  std::promise<bool> registration;
288  auto future = registration.get_future();
289  auto library = GetContext()->GetShaderLibrary();
290  library->RegisterFunction(
291  stage->GetEntrypoint(), //
292  ToShaderStage(stage->GetShaderStage()), //
293  stage->GetCodeMapping(), //
294  fml::MakeCopyable([reg = std::move(registration)](bool result) mutable {
295  reg.set_value(result);
296  }));
297  ASSERT_TRUE(future.get());
298  {
299  auto function =
300  library->GetFunction(stage->GetEntrypoint(), ShaderStage::kFragment);
301  ASSERT_NE(function, nullptr);
302  }
303 
304  // Check if unregistering works.
305 
306  library->UnregisterFunction(stage->GetEntrypoint(), ShaderStage::kFragment);
307  {
308  auto function =
309  library->GetFunction(stage->GetEntrypoint(), ShaderStage::kFragment);
310  ASSERT_EQ(function, nullptr);
311  }
312 }

References impeller::RuntimeStage::DecodeRuntimeStages(), impeller::kFragment, impeller::PlaygroundBackendToRuntimeStageBackend(), and impeller::ToShaderStage().

◆ TEST_P() [443/456]

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(fixture->GetSize(), false));
47  // Not meant to be secure. Just reject obviously bad blobs using magic
48  // numbers.
49  ::memset(junk_allocation->GetBuffer(), 127, junk_allocation->GetLength());
50  auto stages = RuntimeStage::DecodeRuntimeStages(
51  CreateMappingFromAllocation(junk_allocation));
52  ASSERT_FALSE(stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())]);
53 }

References impeller::CreateMappingFromAllocation(), impeller::RuntimeStage::DecodeRuntimeStages(), and impeller::PlaygroundBackendToRuntimeStageBackend().

◆ TEST_P() [444/456]

impeller::testing::TEST_P ( RuntimeStageTest  ,
ContainsExpectedShaderTypes   
)

Definition at line 357 of file runtime_stage_unittests.cc.

357  {
358  auto stages = OpenAssetAsRuntimeStage("ink_sparkle.frag.iplr");
359  // Right now, SkSL gets implicitly bundled regardless of what the build rule
360  // for this test requested. After
361  // https://github.com/flutter/flutter/issues/138919, this may require a build
362  // rule change or a new test.
363  EXPECT_TRUE(stages[RuntimeStageBackend::kSkSL]);
364 
365  EXPECT_TRUE(stages[RuntimeStageBackend::kOpenGLES]);
366  EXPECT_TRUE(stages[RuntimeStageBackend::kMetal]);
367  EXPECT_TRUE(stages[RuntimeStageBackend::kVulkan]);
368 }

References impeller::kMetal, impeller::kOpenGLES, impeller::kSkSL, and impeller::kVulkan.

◆ TEST_P() [445/456]

impeller::testing::TEST_P ( TypographerTest  ,
CanConvertTextBlob   
)

Definition at line 65 of file typographer_unittests.cc.

65  {
66  SkFont font = flutter::testing::CreateTestFontOfSize(12);
67  auto blob = SkTextBlob::MakeFromString(
68  "the quick brown fox jumped over the lazy dog.", font);
69  ASSERT_TRUE(blob);
70  auto frame = MakeTextFrameFromTextBlobSkia(blob);
71  ASSERT_EQ(frame->GetRunCount(), 1u);
72  for (const auto& run : frame->GetRuns()) {
73  ASSERT_TRUE(run.IsValid());
74  ASSERT_EQ(run.GetGlyphCount(), 45u);
75  }
76 }

References impeller::MakeTextFrameFromTextBlobSkia().

◆ TEST_P() [446/456]

impeller::testing::TEST_P ( TypographerTest  ,
CanCreateGlyphAtlas   
)

Definition at line 83 of file typographer_unittests.cc.

83  {
84  auto context = TypographerContextSkia::Make();
85  auto atlas_context =
86  context->CreateGlyphAtlasContext(GlyphAtlas::Type::kAlphaBitmap);
87  auto host_buffer = HostBuffer::Create(GetContext()->GetResourceAllocator());
88  ASSERT_TRUE(context && context->IsValid());
89  SkFont sk_font = flutter::testing::CreateTestFontOfSize(12);
90  auto blob = SkTextBlob::MakeFromString("hello", sk_font);
91  ASSERT_TRUE(blob);
92  auto atlas =
93  CreateGlyphAtlas(*GetContext(), context.get(), *host_buffer,
94  GlyphAtlas::Type::kAlphaBitmap, 1.0f, atlas_context,
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 }

References impeller::HostBuffer::Create(), CreateGlyphAtlas(), impeller::GlyphAtlas::kAlphaBitmap, impeller::TypographerContextSkia::Make(), and impeller::MakeTextFrameFromTextBlobSkia().

◆ TEST_P() [447/456]

impeller::testing::TEST_P ( TypographerTest  ,
CanCreateRenderContext   
)

Definition at line 78 of file typographer_unittests.cc.

78  {
79  auto context = TypographerContextSkia::Make();
80  ASSERT_TRUE(context && context->IsValid());
81 }

References impeller::TypographerContextSkia::Make().

◆ TEST_P() [448/456]

impeller::testing::TEST_P ( TypographerTest  ,
GlyphAtlasIsRecycledIfUnchanged   
)

Definition at line 179 of file typographer_unittests.cc.

179  {
180  auto context = TypographerContextSkia::Make();
181  auto atlas_context =
182  context->CreateGlyphAtlasContext(GlyphAtlas::Type::kAlphaBitmap);
183  auto host_buffer = HostBuffer::Create(GetContext()->GetResourceAllocator());
184  ASSERT_TRUE(context && context->IsValid());
185  SkFont sk_font = flutter::testing::CreateTestFontOfSize(12);
186  auto blob = SkTextBlob::MakeFromString("spooky skellingtons", sk_font);
187  ASSERT_TRUE(blob);
188  auto atlas =
189  CreateGlyphAtlas(*GetContext(), context.get(), *host_buffer,
190  GlyphAtlas::Type::kAlphaBitmap, 1.0f, atlas_context,
192  ASSERT_NE(atlas, nullptr);
193  ASSERT_NE(atlas->GetTexture(), nullptr);
194  ASSERT_EQ(atlas, atlas_context->GetGlyphAtlas());
195 
196  // now attempt to re-create an atlas with the same text blob.
197 
198  auto next_atlas =
199  CreateGlyphAtlas(*GetContext(), context.get(), *host_buffer,
200  GlyphAtlas::Type::kAlphaBitmap, 1.0f, atlas_context,
202  ASSERT_EQ(atlas, next_atlas);
203  ASSERT_EQ(atlas_context->GetGlyphAtlas(), atlas);
204 }

References impeller::HostBuffer::Create(), CreateGlyphAtlas(), impeller::GlyphAtlas::kAlphaBitmap, impeller::TypographerContextSkia::Make(), and impeller::MakeTextFrameFromTextBlobSkia().

◆ TEST_P() [449/456]

impeller::testing::TEST_P ( TypographerTest  ,
GlyphAtlasTextureIsRecycledIfUnchanged   
)

Definition at line 253 of file typographer_unittests.cc.

253  {
254  auto host_buffer = HostBuffer::Create(GetContext()->GetResourceAllocator());
255  auto context = TypographerContextSkia::Make();
256  auto atlas_context =
257  context->CreateGlyphAtlasContext(GlyphAtlas::Type::kAlphaBitmap);
258  ASSERT_TRUE(context && context->IsValid());
259  SkFont sk_font = flutter::testing::CreateTestFontOfSize(12);
260  auto blob = SkTextBlob::MakeFromString("spooky 1", sk_font);
261  ASSERT_TRUE(blob);
262  auto atlas =
263  CreateGlyphAtlas(*GetContext(), context.get(), *host_buffer,
264  GlyphAtlas::Type::kAlphaBitmap, 1.0f, atlas_context,
266  auto old_packer = atlas_context->GetRectPacker();
267 
268  ASSERT_NE(atlas, nullptr);
269  ASSERT_NE(atlas->GetTexture(), nullptr);
270  ASSERT_EQ(atlas, atlas_context->GetGlyphAtlas());
271 
272  auto* first_texture = atlas->GetTexture().get();
273 
274  // Now create a new glyph atlas with a nearly identical blob.
275 
276  auto blob2 = SkTextBlob::MakeFromString("spooky 2", sk_font);
277  auto next_atlas =
278  CreateGlyphAtlas(*GetContext(), context.get(), *host_buffer,
279  GlyphAtlas::Type::kAlphaBitmap, 1.0f, atlas_context,
281  ASSERT_EQ(atlas, next_atlas);
282  auto* second_texture = next_atlas->GetTexture().get();
283 
284  auto new_packer = atlas_context->GetRectPacker();
285 
286  ASSERT_EQ(second_texture, first_texture);
287  ASSERT_EQ(old_packer, new_packer);
288 }

References impeller::HostBuffer::Create(), CreateGlyphAtlas(), impeller::GlyphAtlas::kAlphaBitmap, impeller::TypographerContextSkia::Make(), and impeller::MakeTextFrameFromTextBlobSkia().

◆ TEST_P() [450/456]

impeller::testing::TEST_P ( TypographerTest  ,
GlyphAtlasTextureWillGrowTilMaxTextureSize   
)

Definition at line 419 of file typographer_unittests.cc.

419  {
420  if (GetBackend() == PlaygroundBackend::kOpenGLES) {
421  GTEST_SKIP() << "Atlas growth isn't supported for OpenGLES currently.";
422  }
423 
424  auto host_buffer = HostBuffer::Create(GetContext()->GetResourceAllocator());
425  auto context = TypographerContextSkia::Make();
426  auto atlas_context =
427  context->CreateGlyphAtlasContext(GlyphAtlas::Type::kAlphaBitmap);
428  ASSERT_TRUE(context && context->IsValid());
429  SkFont sk_font = flutter::testing::CreateTestFontOfSize(12);
430  auto blob = SkTextBlob::MakeFromString("A", sk_font);
431  ASSERT_TRUE(blob);
432  auto atlas =
433  CreateGlyphAtlas(*GetContext(), context.get(), *host_buffer,
434  GlyphAtlas::Type::kAlphaBitmap, 1.0f, atlas_context,
436  // Continually append new glyphs until the glyph size grows to the maximum.
437  // Note that the sizes here are more or less experimentally determined, but
438  // the important expectation is that the atlas size will shrink again after
439  // growing to the maximum size.
440  constexpr ISize expected_sizes[13] = {
441  {4096, 4096}, //
442  {4096, 4096}, //
443  {4096, 8192}, //
444  {4096, 8192}, //
445  {4096, 8192}, //
446  {4096, 8192}, //
447  {4096, 16384}, //
448  {4096, 16384}, //
449  {4096, 16384}, //
450  {4096, 16384}, //
451  {4096, 16384}, //
452  {4096, 16384}, //
453  {4096, 4096} // Shrinks!
454  };
455 
456  for (int i = 0; i < 13; i++) {
457  SkFont sk_font = flutter::testing::CreateTestFontOfSize(50 + i);
458  auto blob = SkTextBlob::MakeFromString("A", sk_font);
459 
460  atlas =
461  CreateGlyphAtlas(*GetContext(), context.get(), *host_buffer,
462  GlyphAtlas::Type::kAlphaBitmap, 50 + i, atlas_context,
464  ASSERT_TRUE(!!atlas);
465  EXPECT_EQ(atlas->GetTexture()->GetTextureDescriptor().size,
466  expected_sizes[i]);
467  }
468 }

References impeller::HostBuffer::Create(), CreateGlyphAtlas(), impeller::GlyphAtlas::kAlphaBitmap, impeller::kOpenGLES, impeller::TypographerContextSkia::Make(), and impeller::MakeTextFrameFromTextBlobSkia().

◆ TEST_P() [451/456]

impeller::testing::TEST_P ( TypographerTest  ,
GlyphAtlasWithLotsOfdUniqueGlyphSize   
)

Definition at line 206 of file typographer_unittests.cc.

206  {
207  auto host_buffer = HostBuffer::Create(GetContext()->GetResourceAllocator());
208  auto context = TypographerContextSkia::Make();
209  auto atlas_context =
210  context->CreateGlyphAtlasContext(GlyphAtlas::Type::kAlphaBitmap);
211  ASSERT_TRUE(context && context->IsValid());
212 
213  const char* test_string =
214  "QWERTYUIOPASDFGHJKLZXCVBNMqewrtyuiopasdfghjklzxcvbnm,.<>[]{};':"
215  "2134567890-=!@#$%^&*()_+"
216  "œ∑´®†¥¨ˆøπ““‘‘åß∂ƒ©˙∆˚¬…æ≈ç√∫˜µ≤≥≥≥≥÷¡™£¢∞§¶•ªº–≠⁄€‹›fifl‡°·‚—±Œ„´‰Á¨Ø∏”’/"
217  "* Í˝ */¸˛Ç◊ı˜Â¯˘¿";
218 
219  SkFont sk_font = flutter::testing::CreateTestFontOfSize(12);
220  auto blob = SkTextBlob::MakeFromString(test_string, sk_font);
221  ASSERT_TRUE(blob);
222 
223  FontGlyphMap font_glyph_map;
224  size_t size_count = 8;
225  for (size_t index = 0; index < size_count; index += 1) {
226  MakeTextFrameFromTextBlobSkia(blob)->CollectUniqueFontGlyphPairs(
227  font_glyph_map, 0.6 * index, {0, 0}, {});
228  };
229  auto atlas =
230  context->CreateGlyphAtlas(*GetContext(), GlyphAtlas::Type::kAlphaBitmap,
231  *host_buffer, atlas_context, font_glyph_map);
232  ASSERT_NE(atlas, nullptr);
233  ASSERT_NE(atlas->GetTexture(), nullptr);
234 
235  std::set<uint16_t> unique_glyphs;
236  std::vector<uint16_t> total_glyphs;
237  atlas->IterateGlyphs([&](const ScaledFont& scaled_font,
238  const SubpixelGlyph& glyph, const Rect& rect) {
239  unique_glyphs.insert(glyph.glyph.index);
240  total_glyphs.push_back(glyph.glyph.index);
241  return true;
242  });
243 
244  // These numbers may be different due to subpixel positions.
245  EXPECT_LE(unique_glyphs.size() * size_count, atlas->GetGlyphCount());
246  EXPECT_EQ(total_glyphs.size(), atlas->GetGlyphCount());
247 
248  EXPECT_TRUE(atlas->GetGlyphCount() > 0);
249  EXPECT_TRUE(atlas->GetTexture()->GetSize().width > 0);
250  EXPECT_TRUE(atlas->GetTexture()->GetSize().height > 0);
251 }

References impeller::HostBuffer::Create(), impeller::SubpixelGlyph::glyph, impeller::Glyph::index, impeller::GlyphAtlas::kAlphaBitmap, impeller::TypographerContextSkia::Make(), and impeller::MakeTextFrameFromTextBlobSkia().

◆ TEST_P() [452/456]

impeller::testing::TEST_P ( TypographerTest  ,
GlyphAtlasWithOddUniqueGlyphSize   
)

Definition at line 159 of file typographer_unittests.cc.

159  {
160  auto context = TypographerContextSkia::Make();
161  auto atlas_context =
162  context->CreateGlyphAtlasContext(GlyphAtlas::Type::kAlphaBitmap);
163  auto host_buffer = HostBuffer::Create(GetContext()->GetResourceAllocator());
164  ASSERT_TRUE(context && context->IsValid());
165  SkFont sk_font = flutter::testing::CreateTestFontOfSize(12);
166  auto blob = SkTextBlob::MakeFromString("AGH", sk_font);
167  ASSERT_TRUE(blob);
168  auto atlas =
169  CreateGlyphAtlas(*GetContext(), context.get(), *host_buffer,
170  GlyphAtlas::Type::kAlphaBitmap, 1.0f, atlas_context,
172  ASSERT_NE(atlas, nullptr);
173  ASSERT_NE(atlas->GetTexture(), nullptr);
174 
175  EXPECT_EQ(atlas->GetTexture()->GetSize().width, 4096u);
176  EXPECT_EQ(atlas->GetTexture()->GetSize().height, 1024u);
177 }

References impeller::HostBuffer::Create(), CreateGlyphAtlas(), impeller::GlyphAtlas::kAlphaBitmap, impeller::TypographerContextSkia::Make(), and impeller::MakeTextFrameFromTextBlobSkia().

◆ TEST_P() [453/456]

impeller::testing::TEST_P ( TypographerTest  ,
GlyphColorIsIgnoredForNonEmojiFonts   
)

Definition at line 324 of file typographer_unittests.cc.

324  {
325  auto host_buffer = HostBuffer::Create(GetContext()->GetResourceAllocator());
326  sk_sp<SkFontMgr> font_mgr = txt::GetDefaultFontManager();
327  sk_sp<SkTypeface> typeface =
328  font_mgr->matchFamilyStyle("Arial", SkFontStyle::Normal());
329  SkFont sk_font(typeface, 0.5f);
330 
331  auto context = TypographerContextSkia::Make();
332  auto atlas_context =
333  context->CreateGlyphAtlasContext(GlyphAtlas::Type::kColorBitmap);
334 
335  // Create two frames with the same character and a different color, but as a
336  // non-emoji font the text frame constructor will ignore it.
337  auto frame =
338  MakeTextFrameFromTextBlobSkia(SkTextBlob::MakeFromString("A", sk_font));
339  auto frame_2 =
340  MakeTextFrameFromTextBlobSkia(SkTextBlob::MakeFromString("A", sk_font));
341  auto properties = {
342  GlyphProperties{},
343  GlyphProperties{},
344  };
345 
346  auto next_atlas =
347  CreateGlyphAtlas(*GetContext(), context.get(), *host_buffer,
348  GlyphAtlas::Type::kColorBitmap, 1.0f, atlas_context,
349  {frame, frame_2}, properties);
350 
351  EXPECT_EQ(next_atlas->GetGlyphCount(), 1u);
352 }

References impeller::HostBuffer::Create(), CreateGlyphAtlas(), impeller::GlyphAtlas::kColorBitmap, impeller::TypographerContextSkia::Make(), and impeller::MakeTextFrameFromTextBlobSkia().

◆ TEST_P() [454/456]

impeller::testing::TEST_P ( TypographerTest  ,
GlyphColorIsPartOfCacheKey   
)

Definition at line 290 of file typographer_unittests.cc.

290  {
291  auto host_buffer = HostBuffer::Create(GetContext()->GetResourceAllocator());
292 #if FML_OS_MACOSX
293  auto mapping = flutter::testing::OpenFixtureAsSkData("Apple Color Emoji.ttc");
294 #else
295  auto mapping = flutter::testing::OpenFixtureAsSkData("NotoColorEmoji.ttf");
296 #endif
297  ASSERT_TRUE(mapping);
298  sk_sp<SkFontMgr> font_mgr = txt::GetDefaultFontManager();
299  SkFont emoji_font(font_mgr->makeFromData(mapping), 50.0);
300 
301  auto context = TypographerContextSkia::Make();
302  auto atlas_context =
303  context->CreateGlyphAtlasContext(GlyphAtlas::Type::kColorBitmap);
304 
305  // Create two frames with the same character and a different color, expect
306  // that it adds a character.
307  auto frame = MakeTextFrameFromTextBlobSkia(
308  SkTextBlob::MakeFromString("😂", emoji_font));
309  auto frame_2 = MakeTextFrameFromTextBlobSkia(
310  SkTextBlob::MakeFromString("😂", emoji_font));
311  auto properties = {
312  GlyphProperties{.color = Color::Red()},
313  GlyphProperties{.color = Color::Blue()},
314  };
315 
316  auto next_atlas =
317  CreateGlyphAtlas(*GetContext(), context.get(), *host_buffer,
318  GlyphAtlas::Type::kColorBitmap, 1.0f, atlas_context,
319  {frame, frame_2}, properties);
320 
321  EXPECT_EQ(next_atlas->GetGlyphCount(), 2u);
322 }

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

impeller::testing::TEST_P ( TypographerTest  ,
LazyAtlasTracksColor   
)

Definition at line 120 of file typographer_unittests.cc.

120  {
121  auto host_buffer = HostBuffer::Create(GetContext()->GetResourceAllocator());
122 #if FML_OS_MACOSX
123  auto mapping = flutter::testing::OpenFixtureAsSkData("Apple Color Emoji.ttc");
124 #else
125  auto mapping = flutter::testing::OpenFixtureAsSkData("NotoColorEmoji.ttf");
126 #endif
127  ASSERT_TRUE(mapping);
128  sk_sp<SkFontMgr> font_mgr = txt::GetDefaultFontManager();
129  SkFont emoji_font(font_mgr->makeFromData(mapping), 50.0);
130  SkFont sk_font = flutter::testing::CreateTestFontOfSize(12);
131 
132  auto blob = SkTextBlob::MakeFromString("hello", sk_font);
133  ASSERT_TRUE(blob);
134  auto frame = MakeTextFrameFromTextBlobSkia(blob);
135 
136  ASSERT_FALSE(frame->GetAtlasType() == GlyphAtlas::Type::kColorBitmap);
137 
138  LazyGlyphAtlas lazy_atlas(TypographerContextSkia::Make());
139 
140  lazy_atlas.AddTextFrame(*frame, 1.0f, {0, 0}, {});
141 
143  SkTextBlob::MakeFromString("😀 ", emoji_font));
144 
145  ASSERT_TRUE(frame->GetAtlasType() == GlyphAtlas::Type::kColorBitmap);
146 
147  lazy_atlas.AddTextFrame(*frame, 1.0f, {0, 0}, {});
148 
149  // Creates different atlases for color and red bitmap.
150  auto color_atlas = lazy_atlas.CreateOrGetGlyphAtlas(
151  *GetContext(), *host_buffer, GlyphAtlas::Type::kColorBitmap);
152 
153  auto bitmap_atlas = lazy_atlas.CreateOrGetGlyphAtlas(
154  *GetContext(), *host_buffer, GlyphAtlas::Type::kAlphaBitmap);
155 
156  ASSERT_FALSE(color_atlas == bitmap_atlas);
157 }

References impeller::LazyGlyphAtlas::AddTextFrame(), impeller::HostBuffer::Create(), impeller::LazyGlyphAtlas::CreateOrGetGlyphAtlas(), impeller::GlyphAtlas::kAlphaBitmap, impeller::GlyphAtlas::kColorBitmap, impeller::TypographerContextSkia::Make(), and impeller::MakeTextFrameFromTextBlobSkia().

◆ TEST_P() [456/456]

impeller::testing::TEST_P ( TypographerTest  ,
RectanglePackerAddsNonoverlapingRectangles   
)

Definition at line 354 of file typographer_unittests.cc.

354  {
355  auto packer = RectanglePacker::Factory(200, 100);
356  ASSERT_NE(packer, nullptr);
357  ASSERT_EQ(packer->PercentFull(), 0);
358 
359  const SkIRect packer_area = SkIRect::MakeXYWH(0, 0, 200, 100);
360 
361  IPoint16 first_output = {-1, -1}; // Fill with sentinel values
362  ASSERT_TRUE(packer->AddRect(20, 20, &first_output));
363  // Make sure the rectangle is placed such that it is inside the bounds of
364  // the packer's area.
365  const SkIRect first_rect =
366  SkIRect::MakeXYWH(first_output.x(), first_output.y(), 20, 20);
367  ASSERT_TRUE(SkIRect::Intersects(packer_area, first_rect));
368 
369  // Initial area was 200 x 100 = 20_000
370  // We added 20x20 = 400. 400 / 20_000 == 0.02 == 2%
371  ASSERT_TRUE(flutter::testing::NumberNear(packer->PercentFull(), 0.02));
372 
373  IPoint16 second_output = {-1, -1};
374  ASSERT_TRUE(packer->AddRect(140, 90, &second_output));
375  const SkIRect second_rect =
376  SkIRect::MakeXYWH(second_output.x(), second_output.y(), 140, 90);
377  // Make sure the rectangle is placed such that it is inside the bounds of
378  // the packer's area but not in the are of the first rectangle.
379  ASSERT_TRUE(SkIRect::Intersects(packer_area, second_rect));
380  ASSERT_FALSE(SkIRect::Intersects(first_rect, second_rect));
381 
382  // We added another 90 x 140 = 12_600 units, now taking us to 13_000
383  // 13_000 / 20_000 == 0.65 == 65%
384  ASSERT_TRUE(flutter::testing::NumberNear(packer->PercentFull(), 0.65));
385 
386  // There's enough area to add this rectangle, but no space big enough for
387  // the 50 units of width.
388  IPoint16 output;
389  ASSERT_FALSE(packer->AddRect(50, 50, &output));
390  // Should be unchanged.
391  ASSERT_TRUE(flutter::testing::NumberNear(packer->PercentFull(), 0.65));
392 
393  packer->Reset();
394  // Should be empty now.
395  ASSERT_EQ(packer->PercentFull(), 0);
396 }

References impeller::RectanglePacker::Factory(), NumberNear(), impeller::IPoint16::x(), and impeller::IPoint16::y().

◆ toColor()

flutter::DlColor impeller::testing::toColor ( const float *  components)

Definition at line 41 of file dl_unittests.cc.

41  {
42  return flutter::DlColor(Color::ToIColor(
43  Color(components[0], components[1], components[2], components[3])));
44 }

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 16 of file golden_paths.h.

◆ kFontFixture

constexpr std::string_view impeller::testing::kFontFixture
staticconstexpr
Initial value:
=
"NotoColorEmoji.ttf"

Definition at line 740 of file aiks_unittests.cc.

Referenced by TEST_P().

◆ kPaintVariations

const std::map<std::string, MaskBlurTestConfig> impeller::testing::kPaintVariations
static

Definition at line 378 of file aiks_blur_unittests.cc.

impeller::ISize
ISize64 ISize
Definition: size.h:140
_BLEND_MODE_RESULT_CHECK
#define _BLEND_MODE_RESULT_CHECK(blend_mode)
Definition: geometry_unittests.cc:1655
NumberNear
bool NumberNear(double a, double b)
Definition: geometry_asserts.h:18
ASSERT_COLOR_NEAR
#define ASSERT_COLOR_NEAR(a, b)
Definition: geometry_asserts.h:192
impeller::kFloat
@ kFloat
Definition: runtime_types.h:23
impeller::OptionsFromPass
ContentContextOptions OptionsFromPass(const RenderPass &pass)
Definition: contents.cc:19
impeller::k1OverSqrt2
constexpr float k1OverSqrt2
Definition: constants.h:50
impeller::testing::CompareFunctionUI
static const CompareFunctionUIData & CompareFunctionUI()
Definition: renderer_unittests.cc:1184
impeller::MyMask
Mask< MyMaskBits > MyMask
Definition: base_unittests.cc:20
impeller::BlendModeToString
const char * BlendModeToString(BlendMode blend_mode)
Definition: color.cc:47
polyline
const Path::Polyline & polyline
Definition: stroke_path_geometry.cc:303
impeller::TPoint::y
Type y
Definition: point.h:31
impeller::PixelFormatToString
constexpr const char * PixelFormatToString(PixelFormat format)
Definition: formats.h:140
impeller::Scalar
float Scalar
Definition: scalar.h:18
impeller::skia_conversions::IsNearlySimpleRRect
bool IsNearlySimpleRRect(const SkRRect &rr)
Like SkRRect.isSimple, but allows the corners to differ by kEhCloseEnough.
Definition: skia_conversions.cc:12
impeller::TPoint::Ceil
constexpr TPoint Ceil() const
Definition: point.h:196
impeller::testing::CompareFunctionUIData::IndexOf
int IndexOf(CompareFunction func) const
Definition: renderer_unittests.cc:1167
uvs
Quad uvs
Definition: gaussian_blur_filter_contents.cc:222
impeller::skia_conversions::ConvertStops
void ConvertStops(const flutter::DlGradientColorSourceBase *gradient, std::vector< Color > &colors, std::vector< float > &stops)
Convert display list colors + stops into impeller colors and stops, taking care to ensure that the st...
Definition: skia_conversions.cc:212
impeller::testing::swap_nan
static constexpr Point swap_nan(const Point &point, int index)
Definition: rect_unittests.cc:1305
impeller::skia_conversions::ToSize
Size ToSize(const SkPoint &point)
Definition: skia_conversions.cc:158
impeller::BlendMode
BlendMode
Definition: color.h:59
impeller::testing::CreateMappingFromString
static std::shared_ptr< fml::Mapping > CreateMappingFromString(std::string p_string)
Definition: shader_archive_unittests.cc:15
impeller::TPoint::Lerp
constexpr TPoint Lerp(const TPoint &p, Scalar t) const
Definition: point.h:236
impeller::kEhCloseEnough
constexpr float kEhCloseEnough
Definition: constants.h:56
data
std::shared_ptr< const fml::Mapping > data
Definition: texture_gles.cc:63
font_size
SkScalar font_size
Definition: dl_golden_blur_unittests.cc:22
impeller::TextureDescriptor::format
PixelFormat format
Definition: texture_descriptor.h:41
impeller::TPoint::Min
constexpr TPoint Min(const TPoint &p) const
Definition: point.h:186
impeller::TPoint::Round
static constexpr TPoint Round(const TPoint< U > &other)
Definition: point.h:49
impeller::Vector2
Point Vector2
Definition: point.h:326
EXPECT_POINT_NEAR
#define EXPECT_POINT_NEAR(a, b)
Definition: geometry_asserts.h:205
MatrixNear
inline ::testing::AssertionResult MatrixNear(impeller::Matrix a, impeller::Matrix b)
Definition: geometry_asserts.h:56
impeller::kPi
constexpr float kPi
Definition: constants.h:26
impeller::testing::CanRenderRadialGradientWithDithering
static void CanRenderRadialGradientWithDithering(AiksTest *aiks_test)
Definition: aiks_dl_gradient_unittests.cc:124
impeller::testing::flip_lrtb
static constexpr R flip_lrtb(R rect)
Definition: rect_unittests.cc:1291
impeller::CreateTextureFromDrawableFuture
std::shared_ptr< TextureMTL > CreateTextureFromDrawableFuture(TextureDescriptor desc, const std::shared_future< id< CAMetalDrawable >> &drawble_future)
Create a TextureMTL from a deferred drawable.
Definition: lazy_drawable_holder.mm:41
impeller::kSampledImage
@ kSampledImage
Definition: runtime_types.h:24
impeller::skia_conversions::ToColor
Color ToColor(const flutter::DlColor &color)
Definition: skia_conversions.cc:162
impeller::UintPoint32
TPoint< uint32_t > UintPoint32
Definition: point.h:325
padding
Vector2 padding
The halo padding in source space.
Definition: gaussian_blur_filter_contents.cc:91
buffer_view
BufferView buffer_view
Definition: blit_command_gles.cc:127
impeller::Size
TSize< Scalar > Size
Definition: size.h:137
impeller::StorageMode::kHostVisible
@ kHostVisible
ASSERT_POINT_NEAR
#define ASSERT_POINT_NEAR(a, b)
Definition: geometry_asserts.h:193
impeller::kGaussianBlurMaxKernelSize
static constexpr int32_t kGaussianBlurMaxKernelSize
Definition: gaussian_blur_filter_contents.h:16
impeller::CreateMappingFromAllocation
std::shared_ptr< fml::Mapping > CreateMappingFromAllocation(const std::shared_ptr< Allocation > &allocation)
Definition: allocation.cc:99
ASSERT_VECTOR4_NEAR
#define ASSERT_VECTOR4_NEAR(a, b)
Definition: geometry_asserts.h:195
impeller::PlaygroundBackendToRuntimeStageBackend
constexpr RuntimeStageBackend PlaygroundBackendToRuntimeStageBackend(PlaygroundBackend backend)
Definition: playground.h:33
stroke_width
const Scalar stroke_width
Definition: stroke_path_geometry.cc:304
offset
SeparatedVector2 offset
Definition: stroke_path_geometry.cc:311
impeller::MoveTo
void MoveTo(PathBuilder *builder, Scalar x, Scalar y)
Definition: tessellator.cc:20
EXPECT_RECT_NEAR
#define EXPECT_RECT_NEAR(a, b)
Definition: geometry_asserts.h:203
impeller::GetDrawableDeferred
std::shared_future< id< CAMetalDrawable > > GetDrawableDeferred(CAMetalLayer *layer)
Create a deferred drawable from a CAMetalLayer.
Definition: lazy_drawable_holder.mm:23
impeller::TPoint::Floor
constexpr TPoint Floor() const
Definition: point.h:194
impeller::ToShaderStage
constexpr ShaderStage ToShaderStage(RuntimeShaderStage stage)
Definition: shader_types.h:29
impeller::testing::RenderTextInCanvasSTB
bool RenderTextInCanvasSTB(const std::shared_ptr< Context > &context, Canvas &canvas, const std::string &text, const std::string &font_fixture, TextRenderOptions options={})
Definition: aiks_unittests.cc:590
impeller::kPiOver2
constexpr float kPiOver2
Definition: constants.h:32
impeller::PixelFormat
PixelFormat
The Pixel formats supported by Impeller. The naming convention denotes the usage of the component,...
Definition: formats.h:99
ASSERT_RECT_NEAR
#define ASSERT_RECT_NEAR(a, b)
Definition: geometry_asserts.h:191
impeller::MakeTextFrameSTB
std::shared_ptr< TextFrame > MakeTextFrameSTB(const std::shared_ptr< TypefaceSTB > &typeface_stb, Font::Metrics metrics, const std::string &text)
Definition: text_frame_stb.cc:11
impeller::ToMatrix
static Matrix ToMatrix(const SkMatrix &m)
Definition: dl_dispatcher.cc:161
impeller::kPhi
constexpr float kPhi
Definition: constants.h:53
impeller::VS
SolidFillVertexShader VS
Definition: stroke_path_geometry.cc:16
impeller::saturated::distance
SI distance
Definition: saturated_math.h:57
impeller::testing::toColor
flutter::DlColor toColor(const float *components)
Definition: dl_unittests.cc:41
impeller::Point
TPoint< Scalar > Point
Definition: point.h:322
impeller::k2Pi
constexpr float k2Pi
Definition: constants.h:29
impeller::Quad
std::array< Point, 4 > Quad
Definition: point.h:327
impeller::testing::CompareFunctionUIData::FunctionOf
CompareFunction FunctionOf(int index) const
Definition: renderer_unittests.cc:1177
BLEND_MODE_TUPLE
#define BLEND_MODE_TUPLE(blend_mode)
Definition: aiks_blend_unittests.cc:181
impeller::testing::RGBToYUV
static Vector3 RGBToYUV(Vector3 rgb, YUVColorSpace yuv_color_space)
Definition: entity_unittests.cc:1838
impeller::MipFilter
MipFilter
Options for selecting and filtering between mipmap levels.
Definition: formats.h:419
impeller::testing::flip_lr
static constexpr R flip_lr(R rect)
Definition: rect_unittests.cc:1279
impeller::SPrintF
std::string SPrintF(const char *format,...)
Definition: strings.cc:12
EXPECT_VECTOR3_NEAR
#define EXPECT_VECTOR3_NEAR(a, b)
Definition: geometry_asserts.h:206
transform
Matrix transform
Definition: gaussian_blur_filter_contents.cc:231
impeller::testing::GetBlendModeSelection
static BlendModeSelection GetBlendModeSelection()
Definition: aiks_blend_unittests.cc:188
impeller::IPoint32
TPoint< int32_t > IPoint32
Definition: point.h:324
impeller::ScalarToHalf
constexpr InternalHalf ScalarToHalf(Scalar f)
Convert a scalar to a half precision float.
Definition: half.h:32
impeller::TPoint::Max
constexpr TPoint Max(const TPoint &p) const
Definition: point.h:190
impeller::FontGlyphMap
std::unordered_map< ScaledFont, std::unordered_set< SubpixelGlyph > > FontGlyphMap
Definition: font_glyph_pair.h:54
impeller::testing::CreatePassWithRectPath
auto CreatePassWithRectPath(Rect rect, std::optional< Rect > bounds_hint, ContentBoundsPromise bounds_promise=ContentBoundsPromise::kUnknown, bool collapse=false)
Definition: entity_unittests.cc:110
type
GLenum type
Definition: blit_command_gles.cc:126
impeller::Matrix::MakeColumn
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
impeller::MinMagFilter
MinMagFilter
Describes how the texture should be sampled when the texture is being shrunk (minified) or expanded (...
Definition: formats.h:409
impeller::testing::CreateTestYUVTextures
static std::vector< std::shared_ptr< Texture > > CreateTestYUVTextures(Context *context, YUVColorSpace yuv_color_space)
Definition: entity_unittests.cc:1855
_BLEND_MODE_NAME_CHECK
#define _BLEND_MODE_NAME_CHECK(blend_mode)
Definition: geometry_unittests.cc:1673
impeller::Rect
TRect< Scalar > Rect
Definition: rect.h:769
ASSERT_MATRIX_NEAR
#define ASSERT_MATRIX_NEAR(a, b)
Definition: geometry_asserts.h:189
impeller::testing::CreateStringFromMapping
const std::string CreateStringFromMapping(const fml::Mapping &mapping)
Definition: shader_archive_unittests.cc:23
impeller::TextureUsageMask
Mask< TextureUsage > TextureUsageMask
Definition: formats.h:308
impeller::CreateGradientBuffer
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
impeller::kStruct
@ kStruct
Definition: runtime_types.h:25
impeller::skia_conversions::ToPoint
Point ToPoint(const SkPoint &point)
Definition: skia_conversions.cc:154
impeller::testing::CanRenderConicalGradientWithDithering
static void CanRenderConicalGradientWithDithering(AiksTest *aiks_test)
Definition: aiks_dl_gradient_unittests.cc:167
IMPELLER_FOR_EACH_BLEND_MODE
#define IMPELLER_FOR_EACH_BLEND_MODE(V)
Definition: color.h:19
IMPELLER_RAND
#define IMPELLER_RAND
Definition: gaussian_blur_filter_contents_unittests.cc:18
impeller::MakeTextFrameFromTextBlobSkia
std::shared_ptr< TextFrame > MakeTextFrameFromTextBlobSkia(const sk_sp< SkTextBlob > &blob)
Definition: text_frame_skia.cc:61
impeller::ToMTLPixelFormat
constexpr MTLPixelFormat ToMTLPixelFormat(PixelFormat format)
Definition: formats_mtl.h:76
ASSERT_QUATERNION_NEAR
#define ASSERT_QUATERNION_NEAR(a, b)
Definition: geometry_asserts.h:190
impeller::GenerateBlurInfo
KernelSamples GenerateBlurInfo(BlurParameters parameters)
Definition: gaussian_blur_filter_contents.cc:817
impeller::Close
void Close(PathBuilder *builder)
Definition: tessellator.cc:38
impeller::TextureDescriptor::size
ISize size
Definition: texture_descriptor.h:42
VALIDATION_LOG
#define VALIDATION_LOG
Definition: validation.h:73
impeller::testing::RenderTextInCanvasSkia
bool RenderTextInCanvasSkia(const std::shared_ptr< Context > &context, Canvas &canvas, const std::string &text, const std::string_view &font_fixture, TextRenderOptions options={})
Definition: aiks_unittests.cc:550
impeller::LineTo
void LineTo(PathBuilder *builder, Scalar x, Scalar y)
Definition: tessellator.cc:24
impeller::Join
Join
Definition: path.h:24
RectNear
inline ::testing::AssertionResult RectNear(impeller::Rect a, impeller::Rect b)
Definition: geometry_asserts.h:89
impeller::DrawPlaygroundPoint
Point DrawPlaygroundPoint(PlaygroundPoint &point)
Definition: widgets.cc:9
impeller::testing::CanRenderLinearGradientWithDithering
static void CanRenderLinearGradientWithDithering(AiksTest *aiks_test)
Definition: aiks_dl_gradient_unittests.cc:104
impeller::IPoint
TPoint< int64_t > IPoint
Definition: point.h:323
impeller::MyMaskBits
MyMaskBits
Definition: base_unittests.cc:13
ASSERT_VECTOR3_NEAR
#define ASSERT_VECTOR3_NEAR(a, b)
Definition: geometry_asserts.h:194
FLT_FORWARD
#define FLT_FORWARD(mock, real, method)
Definition: aiks_blur_unittests.cc:499
impeller::saturated::b
SI b
Definition: saturated_math.h:87
impeller::testing::kFontFixture
static constexpr std::string_view kFontFixture
Definition: aiks_unittests.cc:740
scale
const Scalar scale
Definition: stroke_path_geometry.cc:308
blur_radius
Vector2 blur_radius
Blur radius in source pixels based on scaled_sigma.
Definition: gaussian_blur_filter_contents.cc:89
paint
const Paint & paint
Definition: color_source.cc:38
impeller::ScalarNearlyEqual
constexpr bool ScalarNearlyEqual(Scalar x, Scalar y, Scalar tolerance=kEhCloseEnough)
Definition: scalar.h:30
impeller::YUVColorSpace
YUVColorSpace
Definition: color.h:55
impeller::LerpHackKernelSamples
GaussianBlurPipeline::FragmentShader::KernelSamples LerpHackKernelSamples(KernelSamples parameters)
Definition: gaussian_blur_filter_contents.cc:864
impeller::testing::CreateGlyphAtlas
static std::shared_ptr< GlyphAtlas > CreateGlyphAtlas(Context &context, const TypographerContext *typographer_context, HostBuffer &host_buffer, GlyphAtlas::Type type, Scalar scale, const std::shared_ptr< GlyphAtlasContext > &atlas_context, const std::vector< std::shared_ptr< TextFrame >> &frames, const std::vector< GlyphProperties > &properties)
Definition: typographer_unittests.cc:46
impeller::TPoint::Rotate
constexpr TPoint Rotate(const Radians &angle) const
Definition: point.h:226
impeller::SampleCount::kCount1
@ kCount1
impeller::IRect
IRect64 IRect
Definition: rect.h:772
color
DlColor color
Definition: dl_golden_blur_unittests.cc:23
impeller::TextureDescriptor::storage_mode
StorageMode storage_mode
Definition: texture_descriptor.h:39
impeller::TPoint::GetDistance
constexpr Type GetDistance(const TPoint &p) const
Definition: point.h:200
impeller::TextureDescriptor
A lightweight object that describes the attributes of a texture that can then used an allocator to cr...
Definition: texture_descriptor.h:38
impeller::TSize::MipCount
constexpr size_t MipCount() const
Definition: size.h:115
impeller::TPoint::Normalize
constexpr TPoint Normalize() const
Definition: point.h:208
impeller::testing::flip_tb
static constexpr R flip_tb(R rect)
Definition: rect_unittests.cc:1285
ASSERT_COLOR_BUFFER_NEAR
#define ASSERT_COLOR_BUFFER_NEAR(a, b)
Definition: geometry_asserts.h:198
impeller::testing::CanRenderSweepGradientWithDithering
static void CanRenderSweepGradientWithDithering(AiksTest *aiks_test)
Definition: aiks_dl_gradient_unittests.cc:144
impeller::kPiOver4
constexpr float kPiOver4
Definition: constants.h:35
impeller::MakeVertices
std::shared_ptr< impeller::VerticesGeometry > MakeVertices(const std::shared_ptr< const flutter::DlVertices > &vertices)
Definition: dl_vertices_geometry.cc:31
impeller::Cap
Cap
Definition: path.h:18
ASSERT_ARRAY_4_NEAR
#define ASSERT_ARRAY_4_NEAR(a, b)
Definition: geometry_asserts.h:197
IPLR_REQUIRES
#define IPLR_REQUIRES(...)
Definition: thread_safety.h:30
impeller::DrawPlaygroundLine
std::tuple< Point, Point > DrawPlaygroundLine(PlaygroundPoint &point_a, PlaygroundPoint &point_b)
Definition: widgets.cc:50