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, 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, 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)
 
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/452]

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

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

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

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

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

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

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

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

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

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

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

Definition at line 843 of file aiks_unittests.cc.

843  {
844  Canvas canvas;
845  canvas.Scale(Vector2(0.2, 0.2));
846  canvas.DrawPaint({.color = Color::MediumTurquoise()});
847  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
848 }

References impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::MediumTurquoise(), and impeller::Canvas::Scale().

◆ TEST_P() [12/452]

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

Definition at line 850 of file aiks_unittests.cc.

850  {
851  Canvas canvas;
852  canvas.Scale(Vector2(0.2, 0.2));
853  canvas.DrawPaint({.color = Color::MediumTurquoise()});
854  canvas.DrawPaint({.color = Color::Color::OrangeRed().WithAlpha(0.5)});
855  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
856 }

References impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::MediumTurquoise(), and impeller::Canvas::Scale().

◆ TEST_P() [13/452]

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

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

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

Definition at line 2693 of file aiks_unittests.cc.

2693  {
2694  // Avoiding `GetSecondsElapsed()` to reduce risk of golden flakiness.
2695  int time = 0;
2696  auto callback = [&](AiksContext& renderer) -> std::optional<Picture> {
2697  Canvas canvas;
2698 
2699  canvas.Save();
2700  {
2701  canvas.Translate({300, 300});
2702 
2703  // 1. Draw/restore a clip before drawing the image, which will get drawn
2704  // to the depth buffer behind the image.
2705  canvas.Save();
2706  {
2707  canvas.DrawPaint({.color = Color::Green()});
2708  canvas.ClipRect(Rect::MakeLTRB(-180, -180, 180, 180),
2709  Entity::ClipOperation::kDifference);
2710  canvas.DrawPaint({.color = Color::Black()});
2711  }
2712  canvas.Restore(); // Restore rectangle difference clip.
2713 
2714  canvas.Save();
2715  {
2716  // 2. Draw an oval clip that applies to the image, which will get drawn
2717  // in front of the image on the depth buffer.
2718  canvas.ClipOval(Rect::MakeLTRB(-200, -200, 200, 200));
2719 
2720  // 3. Draw the rotating image with a perspective transform.
2721  canvas.Transform(
2722  Matrix(1.0, 0.0, 0.0, 0.0, //
2723  0.0, 1.0, 0.0, 0.0, //
2724  0.0, 0.0, 1.0, 0.003, //
2725  0.0, 0.0, 0.0, 1.0) * //
2726  Matrix::MakeRotationY({Radians{-1.0f + (time++ / 60.0f)}}));
2727  auto image =
2728  std::make_shared<Image>(CreateTextureForFixture("airplane.jpg"));
2729  canvas.DrawImage(image, -Point(image->GetSize()) / 2, {});
2730  }
2731  canvas.Restore(); // Restore oval intersect clip.
2732 
2733  // 4. Draw a semi-translucent blue circle atop all previous draws.
2734  canvas.DrawCircle({}, 230, {.color = Color::Blue().WithAlpha(0.4)});
2735  }
2736  canvas.Restore(); // Restore translation.
2737 
2738  return canvas.EndRecordingAsPicture();
2739  };
2740  ASSERT_TRUE(OpenPlaygroundHere(callback));
2741 }

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

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

Definition at line 2231 of file aiks_unittests.cc.

2231  {
2232  std::vector<Point> points = {
2233  {0, 0}, //
2234  {100, 100}, //
2235  {100, 0}, //
2236  {0, 100}, //
2237  {0, 0}, //
2238  {48, 48}, //
2239  {52, 52}, //
2240  };
2241  std::vector<PointStyle> caps = {
2242  PointStyle::kRound,
2243  PointStyle::kSquare,
2244  };
2245  Paint paint;
2246  paint.color = Color::Yellow().WithAlpha(0.5);
2247 
2248  Paint background;
2249  background.color = Color::Black();
2250 
2251  Canvas canvas;
2252  canvas.DrawPaint(background);
2253  canvas.Translate({200, 200});
2254  canvas.DrawPoints(points, 10, paint, PointStyle::kRound);
2255  canvas.Translate({150, 0});
2256  canvas.DrawPoints(points, 10, paint, PointStyle::kSquare);
2257 
2258  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2259 }

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

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

Definition at line 2261 of file aiks_unittests.cc.

2261  {
2262  auto texture = CreateTextureForFixture("table_mountain_nx.png",
2263  /*enable_mipmapping=*/true);
2264 
2265  std::vector<Point> points = {
2266  {0, 0}, //
2267  {100, 100}, //
2268  {100, 0}, //
2269  {0, 100}, //
2270  {0, 0}, //
2271  {48, 48}, //
2272  {52, 52}, //
2273  };
2274  std::vector<PointStyle> caps = {
2275  PointStyle::kRound,
2276  PointStyle::kSquare,
2277  };
2278  Paint paint;
2279  paint.color_source = ColorSource::MakeImage(texture, Entity::TileMode::kClamp,
2280  Entity::TileMode::kClamp, {}, {});
2281 
2282  Canvas canvas;
2283  canvas.Translate({200, 200});
2284  canvas.DrawPoints(points, 100, paint, PointStyle::kRound);
2285  canvas.Translate({150, 0});
2286  canvas.DrawPoints(points, 100, paint, PointStyle::kSquare);
2287 
2288  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2289 }

References impeller::Entity::kClamp, impeller::kRound, impeller::kSquare, impeller::ColorSource::MakeImage(), paint, and impeller::Canvas::Translate().

◆ TEST_P() [18/452]

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

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

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

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

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

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

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

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

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

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

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

Definition at line 2743 of file aiks_unittests.cc.

2743  {
2744  Canvas canvas;
2745  Paint paint;
2746 
2747  canvas.Scale(GetContentScale());
2748 
2749  // Draw something interesting in the background.
2750  std::vector<Color> colors = {Color{0.9568, 0.2627, 0.2118, 1.0},
2751  Color{0.1294, 0.5882, 0.9529, 1.0}};
2752  std::vector<Scalar> stops = {
2753  0.0,
2754  1.0,
2755  };
2756  paint.color_source = ColorSource::MakeLinearGradient(
2757  {0, 0}, {100, 100}, std::move(colors), std::move(stops),
2758  Entity::TileMode::kRepeat, {});
2759  canvas.DrawPaint(paint);
2760 
2761  Rect clip_rect = Rect::MakeLTRB(50, 50, 400, 300);
2762 
2763  // Draw a clipped SaveLayer, where the clip coverage and SaveLayer size are
2764  // the same.
2765  canvas.ClipRRect(clip_rect, Size(100, 100),
2766  Entity::ClipOperation::kIntersect);
2767  canvas.SaveLayer({}, clip_rect,
2768  ImageFilter::MakeFromColorFilter(*ColorFilter::MakeBlend(
2769  BlendMode::kExclusion, Color::Red())));
2770  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2771 }

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

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

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

Definition at line 1457 of file aiks_unittests.cc.

1457  {
1458  Canvas canvas;
1459 
1460  canvas.DrawPaint({.color = Color::White()});
1461 
1462  // Draw a green circle on the screen.
1463  {
1464  // Increase the clip depth for the savelayer to contend with.
1465  canvas.ClipPath(PathBuilder{}.AddCircle({100, 100}, 50).TakePath());
1466 
1467  canvas.SaveLayer({}, Rect::MakeXYWH(50, 50, 100, 100));
1468 
1469  // Fill the layer with white.
1470  canvas.DrawRect(Rect::MakeSize(Size{400, 400}), {.color = Color::White()});
1471  // Fill the layer with green, but do so with a color blend that can't be
1472  // collapsed into the parent pass.
1473  // TODO(jonahwilliams): this blend mode was changed from color burn to
1474  // hardlight to work around https://github.com/flutter/flutter/issues/136554
1475  // .
1476  canvas.DrawRect(
1477  Rect::MakeSize(Size{400, 400}),
1478  {.color = Color::Green(), .blend_mode = BlendMode::kHardLight});
1479  }
1480 
1481  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1482 }

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

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

Definition at line 2169 of file aiks_unittests.cc.

2169  {
2170  auto runtime_stages =
2171  OpenAssetAsRuntimeStage("runtime_stage_example.frag.iplr");
2172 
2173  auto runtime_stage =
2174  runtime_stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
2175  ASSERT_TRUE(runtime_stage);
2176  ASSERT_TRUE(runtime_stage->IsDirty());
2177 
2178  struct FragUniforms {
2179  Vector2 iResolution;
2180  Scalar iTime;
2181  } frag_uniforms = {.iResolution = Vector2(400, 400), .iTime = 100.0};
2182  auto uniform_data = std::make_shared<std::vector<uint8_t>>();
2183  uniform_data->resize(sizeof(FragUniforms));
2184  memcpy(uniform_data->data(), &frag_uniforms, sizeof(FragUniforms));
2185 
2186  std::vector<RuntimeEffectContents::TextureInput> texture_inputs;
2187 
2188  Paint paint;
2189  paint.color_source = ColorSource::MakeRuntimeEffect(
2190  runtime_stage, uniform_data, texture_inputs);
2191 
2192  Canvas canvas;
2193  canvas.Save();
2194  canvas.ClipRRect(Rect::MakeXYWH(0, 0, 400, 400), {10.0, 10.0},
2195  Entity::ClipOperation::kIntersect);
2196  canvas.DrawRect(Rect::MakeXYWH(0, 0, 400, 400), paint);
2197  canvas.Restore();
2198 
2199  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2200 }

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

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

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

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

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

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

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

Definition at line 186 of file aiks_dl_gradient_unittests.cc.

186  {
188 }

References CanRenderConicalGradientWithDithering().

◆ TEST_P() [38/452]

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

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

Definition at line 2154 of file aiks_unittests.cc.

2154  {
2155  Canvas canvas;
2156 
2157  canvas.DrawPaint({.color = Color::Red()});
2158  // Draw an empty savelayer with a destructive blend mode, which will replace
2159  // the entire red screen with fully transparent black, except for the green
2160  // circle drawn within the layer.
2161  canvas.SaveLayer({.blend_mode = BlendMode::kSource});
2162  canvas.DrawCircle({300, 300}, 100, {.color = Color::Green()});
2163  canvas.Restore();
2164 
2165  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2166 }

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

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

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

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

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

Definition at line 735 of file aiks_unittests.cc.

735  {
736  Canvas canvas;
737  canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)});
738 
739  ASSERT_TRUE(RenderTextInCanvasSkia(
740  GetContext(), canvas, "😀 😃 😄 😁 😆 😅 😂 🤣 🥲 😊", kFontFixture));
741  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
742 }

References impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), kFontFixture, and RenderTextInCanvasSkia().

◆ TEST_P() [44/452]

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

Definition at line 757 of file aiks_unittests.cc.

757  {
758  Canvas canvas;
759  canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)});
760 
761  ASSERT_TRUE(RenderTextInCanvasSkia(
762  GetContext(), canvas, "😀 😃 😄 😁 😆 😅 😂 🤣 🥲 😊", kFontFixture,
763  {.color = Color::Black().WithAlpha(0.5)}));
764  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
765 }

References impeller::Color::Black(), impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), kFontFixture, RenderTextInCanvasSkia(), and impeller::Color::WithAlpha().

◆ TEST_P() [45/452]

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

Definition at line 744 of file aiks_unittests.cc.

744  {
745  Canvas canvas;
746  canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)});
747 
748  ASSERT_TRUE(RenderTextInCanvasSkia(
749  GetContext(), canvas, "😀 😃 😄 😁 😆 😅 😂 🤣 🥲 😊", kFontFixture,
750  TextRenderOptions{.color = Color::Blue(),
751  .mask_blur_descriptor = Paint::MaskBlurDescriptor{
752  .style = FilterContents::BlurStyle::kNormal,
753  .sigma = Sigma(4)}}));
754  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
755 }

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

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

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

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

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

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

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

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

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

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

Definition at line 718 of file aiks_unittests.cc.

718  {
719  Canvas canvas;
720  canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)});
721 
722  ASSERT_TRUE(RenderTextInCanvasSkia(
723  GetContext(), canvas, "the quick brown fox jumped over the lazy dog!.?",
724  "HomemadeApple.ttf"));
725  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
726 }

References impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), and RenderTextInCanvasSkia().

◆ TEST_P() [55/452]

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

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

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

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

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

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

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

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

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

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

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

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

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

Definition at line 120 of file aiks_dl_gradient_unittests.cc.

120  {
122 }

References CanRenderLinearGradientWithDithering().

◆ TEST_P() [68/452]

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

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

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

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

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

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

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

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

Definition at line 140 of file aiks_dl_gradient_unittests.cc.

140  {
142 }

References CanRenderRadialGradientWithDithering().

◆ TEST_P() [76/452]

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

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

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

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  ASSERT_TRUE(RenderTextInCanvasSkia(
633  GetContext(), canvas, "the quick brown fox jumped over the lazy dog!.?",
634  "Roboto-Regular.ttf",
635  {
636  .stroke = true,
637  }));
638  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
639 }

References impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), and RenderTextInCanvasSkia().

◆ TEST_P() [79/452]

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

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

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

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

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

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

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

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

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

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

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

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

Definition at line 163 of file aiks_dl_gradient_unittests.cc.

163  {
165 }

References CanRenderSweepGradientWithDithering().

◆ TEST_P() [91/452]

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

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

Definition at line 661 of file aiks_unittests.cc.

661  {
662  Canvas canvas;
663  canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)});
664  ASSERT_TRUE(RenderTextInCanvasSTB(
665  GetContext(), canvas, "the quick brown fox jumped over the lazy dog!.?",
666  "Roboto-Regular.ttf"));
667 
668  SetTypographerContext(TypographerContextSTB::Make());
669  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
670 }

References impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), impeller::TypographerContextSTB::Make(), and RenderTextInCanvasSTB().

◆ TEST_P() [93/452]

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

Definition at line 651 of file aiks_unittests.cc.

651  {
652  Canvas canvas;
653  canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)});
654  canvas.Scale({2.625, 2.625, 1});
655  ASSERT_TRUE(RenderTextInCanvasSkia(
656  GetContext(), canvas, "the quick brown fox jumped over the lazy dog!.?",
657  "Roboto-Regular.ttf"));
658  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
659 }

References impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), RenderTextInCanvasSkia(), and impeller::Canvas::Scale().

◆ TEST_P() [94/452]

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

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  canvas.Scale({0.5, 0.5, 1});
645  ASSERT_TRUE(RenderTextInCanvasSkia(
646  GetContext(), canvas, "the quick brown fox jumped over the lazy dog!.?",
647  "Roboto-Regular.ttf"));
648  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
649 }

References impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), RenderTextInCanvasSkia(), and impeller::Canvas::Scale().

◆ TEST_P() [95/452]

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

Definition at line 767 of file aiks_unittests.cc.

767  {
768  Canvas canvas;
769  canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)});
770 
771  canvas.Translate({100, 100});
772  canvas.Scale(Vector2{0.5, 0.5});
773 
774  // Blend the layer with the parent pass using kClear to expose the coverage.
775  canvas.SaveLayer({.blend_mode = BlendMode::kClear});
776  ASSERT_TRUE(RenderTextInCanvasSkia(
777  GetContext(), canvas, "the quick brown fox jumped over the lazy dog!.?",
778  "Roboto-Regular.ttf"));
779  canvas.Restore();
780 
781  // Render the text again over the cleared coverage rect.
782  ASSERT_TRUE(RenderTextInCanvasSkia(
783  GetContext(), canvas, "the quick brown fox jumped over the lazy dog!.?",
784  "Roboto-Regular.ttf"));
785 
786  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
787 }

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

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

Definition at line 789 of file aiks_unittests.cc.

789  {
790  Canvas canvas;
791  canvas.Translate({200, 150});
792 
793  // Construct the text blob.
794  auto mapping = flutter::testing::OpenFixtureAsSkData("wtf.otf");
795  ASSERT_NE(mapping, nullptr);
796 
797  Scalar font_size = 80;
798  sk_sp<SkFontMgr> font_mgr = txt::GetDefaultFontManager();
799  SkFont sk_font(font_mgr->makeFromData(mapping), font_size);
800 
801  Paint text_paint;
802  text_paint.color = Color::Blue().WithAlpha(0.8);
803 
804  struct {
805  Point position;
806  const char* text;
807  } text[] = {{Point(0, 0), "0F0F0F0"},
808  {Point(1, 2), "789"},
809  {Point(1, 3), "456"},
810  {Point(1, 4), "123"},
811  {Point(0, 6), "0F0F0F0"}};
812  for (auto& t : text) {
813  canvas.Save();
814  canvas.Translate(t.position * Point(font_size * 2, font_size * 1.1));
815  {
816  auto blob = SkTextBlob::MakeFromString(t.text, sk_font);
817  ASSERT_NE(blob, nullptr);
818  auto frame = MakeTextFrameFromTextBlobSkia(blob);
819  canvas.DrawTextFrame(frame, Point(), text_paint);
820  }
821  canvas.Restore();
822  }
823 
824  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
825 }

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

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

Definition at line 2848 of file aiks_unittests.cc.

2848  {
2849  // Verifies that text scales are clamped to work around
2850  // https://github.com/flutter/flutter/issues/136112 .
2851 
2852  Canvas canvas;
2853  Paint save_paint;
2854  canvas.SaveLayer(save_paint);
2855  canvas.Transform(Matrix(2000, 0, 0, 0, //
2856  0, 2000, 0, 0, //
2857  0, 0, -1, 9000, //
2858  0, 0, -1, 7000 //
2859  ));
2860 
2861  ASSERT_TRUE(RenderTextInCanvasSkia(GetContext(), canvas, "Hello world",
2862  "Roboto-Regular.ttf"));
2863  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2864 }

References impeller::Canvas::EndRecordingAsPicture(), RenderTextInCanvasSkia(), impeller::Canvas::SaveLayer(), and impeller::Canvas::Transform().

◆ TEST_P() [98/452]

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

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

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

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

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

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

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

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 2108 of file aiks_unittests.cc.

2108  {
2109  Canvas canvas;
2110  canvas.DrawPaint({.color = Color::Red()});
2111 
2112  // Draw two overlapping subpixel circles.
2113  canvas.SaveLayer({});
2114  canvas.DrawCircle({100, 100}, 0.1, {.color = Color::Yellow()});
2115  canvas.Restore();
2116  canvas.SaveLayer({});
2117  canvas.DrawCircle({100, 100}, 0.1, {.color = Color::Yellow()});
2118  canvas.Restore();
2119 
2120  canvas.DrawPaint({.color = Color::Green()});
2121 
2122  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2123 }

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

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

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

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

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

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

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

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

Definition at line 1733 of file aiks_unittests.cc.

1733  {
1734  Canvas canvas;
1735  canvas.SaveLayer({}, std::nullopt,
1736  ImageFilter::MakeBlur(Sigma(3), Sigma(3),
1737  FilterContents::BlurStyle::kNormal,
1738  Entity::TileMode::kClamp));
1739  canvas.DrawPaint({.color = Color::Red(), .blend_mode = BlendMode::kSource});
1740  canvas.DrawPaint({.color = Color::CornflowerBlue().WithAlpha(0.75),
1741  .blend_mode = BlendMode::kSourceOver});
1742  canvas.Restore();
1743 
1744  Picture picture = canvas.EndRecordingAsPicture();
1745 
1746  std::optional<Color> actual_color;
1747  bool found_subpass = false;
1748  picture.pass->IterateAllElements([&](EntityPass::Element& element) -> bool {
1749  if (auto subpass = std::get_if<std::unique_ptr<EntityPass>>(&element)) {
1750  actual_color = subpass->get()->GetClearColor();
1751  found_subpass = true;
1752  }
1753  // Fail if the first element isn't a subpass.
1754  return true;
1755  });
1756 
1757  EXPECT_TRUE(found_subpass);
1758  EXPECT_FALSE(actual_color.has_value());
1759 }

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

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

Definition at line 2537 of file aiks_unittests.cc.

2537  {
2538  SetWindowSize({400, 400});
2539  Canvas canvas;
2540  canvas.Scale(GetContentScale());
2541  canvas.DrawRect(Rect::MakeLTRB(200, 200, 300, 300), {.color = Color::Red()});
2542  canvas.SaveLayer({
2543  .image_filter = std::make_shared<MatrixImageFilter>(
2544  Matrix::MakeScale({2, 2, 1}), SamplerDescriptor{}),
2545  });
2546  // Draw a rectangle that would fully cover the parent pass size, but not
2547  // the subpass that it is rendered in.
2548  canvas.DrawRect(Rect::MakeLTRB(0, 0, 400, 400), {.color = Color::Green()});
2549  // Draw a bigger rectangle to force the subpass to be bigger.
2550  canvas.DrawRect(Rect::MakeLTRB(0, 0, 800, 800), {.color = Color::Red()});
2551  canvas.Restore();
2552 
2553  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2554 }

References impeller::Color::Green(), impeller::TRect< Scalar >::MakeLTRB(), impeller::Matrix::MakeScale(), impeller::Color::Red(), and impeller::Canvas::Scale().

◆ TEST_P() [114/452]

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

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

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

Definition at line 1709 of file aiks_unittests.cc.

1709  {
1710  Canvas canvas(Rect::MakeXYWH(0, 0, 100, 100));
1711  canvas.ClipRect(Rect::MakeXYWH(0, 0, 100, 100));
1712  canvas.ClipRect(Rect::MakeXYWH(-100, -100, 300, 300));
1713  canvas.DrawPaint({.color = Color::Red(), .blend_mode = BlendMode::kSource});
1714  canvas.DrawPaint({.color = Color::CornflowerBlue().WithAlpha(0.75),
1715  .blend_mode = BlendMode::kSourceOver});
1716 
1717  Picture picture = canvas.EndRecordingAsPicture();
1718  auto expected = Color::Red().Blend(Color::CornflowerBlue().WithAlpha(0.75),
1719  BlendMode::kSourceOver);
1720  ASSERT_EQ(picture.pass->GetClearColor(), expected);
1721 
1722  std::shared_ptr<ContextSpy> spy = ContextSpy::Make();
1723  std::shared_ptr<Context> real_context = GetContext();
1724  std::shared_ptr<ContextMock> mock_context = spy->MakeContext(real_context);
1725  AiksContext renderer(mock_context, nullptr);
1726  std::shared_ptr<Image> image = picture.ToImage(renderer, {300, 300});
1727 
1728  ASSERT_EQ(spy->render_passes_.size(), 1llu);
1729  std::shared_ptr<RenderPass> render_pass = spy->render_passes_[0];
1730  ASSERT_EQ(render_pass->GetCommands().size(), 0llu);
1731 }

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

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

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

Definition at line 1761 of file aiks_unittests.cc.

1761  {
1762  Canvas canvas;
1763  canvas.DrawPaint(
1764  {.color = Color::Yellow(), .blend_mode = BlendMode::kSource});
1765  canvas.SaveLayer({.blend_mode = BlendMode::kMultiply});
1766  canvas.DrawPaint({.color = Color::CornflowerBlue().WithAlpha(0.75),
1767  .blend_mode = BlendMode::kSourceOver});
1768 
1769  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1770 }

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

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

Definition at line 1772 of file aiks_unittests.cc.

1772  {
1773  // Bug: https://github.com/flutter/flutter/issues/131576
1774  Canvas canvas;
1775  canvas.DrawPaint(
1776  {.color = Color::Yellow(), .blend_mode = BlendMode::kSource});
1777  canvas.SaveLayer({}, {},
1778  ImageFilter::MakeBlur(Sigma(20.0), Sigma(20.0),
1779  FilterContents::BlurStyle::kNormal,
1780  Entity::TileMode::kDecal));
1781  canvas.DrawPaint(
1782  {.color = Color::CornflowerBlue(), .blend_mode = BlendMode::kSourceOver});
1783 
1784  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1785 }

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

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

Definition at line 1787 of file aiks_unittests.cc.

1787  {
1788  Canvas canvas;
1789 
1790  canvas.SaveLayer({
1791  .color_filter =
1792  ColorFilter::MakeMatrix({.array =
1793  {
1794  -1.0, 0, 0, 1.0, 0, //
1795  0, -1.0, 0, 1.0, 0, //
1796  0, 0, -1.0, 1.0, 0, //
1797  1.0, 1.0, 1.0, 1.0, 0 //
1798  }}),
1799  });
1800 
1801  canvas.Translate({500, 300, 0});
1802  canvas.Rotate(Radians(2 * kPi / 3));
1803  canvas.DrawRect(Rect::MakeXYWH(100, 100, 200, 200), {.color = Color::Blue()});
1804 
1805  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1806 }

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

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

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

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

Definition at line 2646 of file aiks_unittests.cc.

2646  {
2647  Canvas canvas; // Depth 1 (base pass)
2648  canvas.DrawRRect(Rect::MakeLTRB(0, 0, 100, 100), {10, 10}, {}); // Depth 2
2649  canvas.Save();
2650  {
2651  canvas.ClipRRect(Rect::MakeLTRB(0, 0, 50, 50), {10, 10}, {}); // Depth 4
2652  canvas.SaveLayer({}); // Depth 4
2653  {
2654  canvas.DrawRRect(Rect::MakeLTRB(0, 0, 50, 50), {10, 10}, {}); // Depth 3
2655  }
2656  canvas.Restore(); // Restore the savelayer.
2657  }
2658  canvas.Restore(); // Depth 5 -- this will no longer append a restore entity
2659  // once we switch to the clip depth approach.
2660 
2661  auto picture = canvas.EndRecordingAsPicture();
2662 
2663  std::vector<uint32_t> expected = {
2664  2, // DrawRRect
2665  4, // ClipRRect -- Has a depth value equal to the max depth of all the
2666  // content it affect. In this case, the SaveLayer and all
2667  // its contents are affected.
2668  4, // SaveLayer -- The SaveLayer is drawn to the parent pass after its
2669  // contents are rendered, so it should have a depth value
2670  // greater than all its contents.
2671  3, // DrawRRect
2672  5, // Restore (no longer necessary when clipping on the depth buffer)
2673  };
2674 
2675  std::vector<uint32_t> actual;
2676 
2677  picture.pass->IterateAllElements([&](EntityPass::Element& element) -> bool {
2678  if (auto* subpass = std::get_if<std::unique_ptr<EntityPass>>(&element)) {
2679  actual.push_back(subpass->get()->GetClipDepth());
2680  }
2681  if (Entity* entity = std::get_if<Entity>(&element)) {
2682  actual.push_back(entity->GetClipDepth());
2683  }
2684  return true;
2685  });
2686 
2687  ASSERT_EQ(actual.size(), expected.size());
2688  for (size_t i = 0; i < expected.size(); i++) {
2689  EXPECT_EQ(expected[i], actual[i]) << "Index: " << i;
2690  }
2691 }

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

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

Definition at line 1365 of file aiks_unittests.cc.

1365  {
1366  auto callback = [&](AiksContext& renderer) -> std::optional<Picture> {
1367  Canvas canvas;
1368  canvas.Scale(GetContentScale());
1369 
1370  Paint alpha;
1371  alpha.color = Color::Red().WithAlpha(0.5);
1372 
1373  auto current = Point{25, 25};
1374  const auto offset = Point{25, 25};
1375  const auto size = Size(100, 100);
1376 
1377  static PlaygroundPoint point_a(Point(40, 40), 10, Color::White());
1378  static PlaygroundPoint point_b(Point(160, 160), 10, Color::White());
1379  auto [b0, b1] = DrawPlaygroundLine(point_a, point_b);
1380  auto bounds = Rect::MakeLTRB(b0.x, b0.y, b1.x, b1.y);
1381 
1382  canvas.DrawRect(bounds, Paint{.color = Color::Yellow(),
1383  .stroke_width = 5.0f,
1384  .style = Paint::Style::kStroke});
1385 
1386  canvas.SaveLayer(alpha, bounds);
1387 
1388  canvas.DrawRect(Rect::MakeOriginSize(current, size),
1389  Paint{.color = Color::Red()});
1390  canvas.DrawRect(Rect::MakeOriginSize(current += offset, size),
1391  Paint{.color = Color::Green()});
1392  canvas.DrawRect(Rect::MakeOriginSize(current += offset, size),
1393  Paint{.color = Color::Blue()});
1394 
1395  canvas.Restore();
1396 
1397  return canvas.EndRecordingAsPicture();
1398  };
1399 
1400  ASSERT_TRUE(OpenPlaygroundHere(callback));
1401 }

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

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

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

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

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

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

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

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

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

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

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

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

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

Definition at line 1582 of file aiks_unittests.cc.

1582  {
1583  Canvas canvas;
1584  canvas.DrawPaint({.color = Color::Red(), .blend_mode = BlendMode::kSource});
1585  canvas.DrawPaint({.color = Color::CornflowerBlue().WithAlpha(0.75),
1586  .blend_mode = BlendMode::kSourceOver});
1587 
1588  Picture picture = canvas.EndRecordingAsPicture();
1589  auto expected = Color::Red().Blend(Color::CornflowerBlue().WithAlpha(0.75),
1590  BlendMode::kSourceOver);
1591  ASSERT_EQ(picture.pass->GetClearColor(), expected);
1592 
1593  std::shared_ptr<ContextSpy> spy = ContextSpy::Make();
1594  std::shared_ptr<Context> real_context = GetContext();
1595  std::shared_ptr<ContextMock> mock_context = spy->MakeContext(real_context);
1596  AiksContext renderer(mock_context, nullptr);
1597  std::shared_ptr<Image> image = picture.ToImage(renderer, {300, 300});
1598 
1599  ASSERT_EQ(spy->render_passes_.size(), 1llu);
1600  std::shared_ptr<RenderPass> render_pass = spy->render_passes_[0];
1601  ASSERT_EQ(render_pass->GetCommands().size(), 0llu);
1602 }

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

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

Definition at line 2202 of file aiks_unittests.cc.

2202  {
2203  auto runtime_stages = OpenAssetAsRuntimeStage("gradient.frag.iplr");
2204  auto runtime_stage =
2205  runtime_stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
2206  ASSERT_TRUE(runtime_stage);
2207  ASSERT_TRUE(runtime_stage->IsDirty());
2208 
2209  struct FragUniforms {
2210  Size size;
2211  } frag_uniforms = {.size = Size::MakeWH(400, 400)};
2212  auto uniform_data = std::make_shared<std::vector<uint8_t>>();
2213  uniform_data->resize(sizeof(FragUniforms));
2214  memcpy(uniform_data->data(), &frag_uniforms, sizeof(FragUniforms));
2215 
2216  std::vector<RuntimeEffectContents::TextureInput> texture_inputs;
2217 
2218  Paint paint;
2219  paint.color_source = ColorSource::MakeRuntimeEffect(
2220  runtime_stage, uniform_data, texture_inputs);
2221 
2222  Canvas canvas;
2223  canvas.Save();
2224  canvas.Scale(GetContentScale());
2225  canvas.DrawPaint(paint);
2226  canvas.Restore();
2227 
2228  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2229 }

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

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

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

Definition at line 1629 of file aiks_unittests.cc.

1629  {
1630  Canvas canvas;
1631  canvas.DrawRect(Rect::MakeXYWH(0, 0, 300, 300),
1632  {.color = Color::Red(), .blend_mode = BlendMode::kSource});
1633  canvas.DrawRect(Rect::MakeXYWH(0, 0, 300, 300),
1634  {.color = Color::CornflowerBlue().WithAlpha(0.75),
1635  .blend_mode = BlendMode::kSourceOver});
1636 
1637  std::shared_ptr<ContextSpy> spy = ContextSpy::Make();
1638  Picture picture = canvas.EndRecordingAsPicture();
1639  std::shared_ptr<Context> real_context = GetContext();
1640  std::shared_ptr<ContextMock> mock_context = spy->MakeContext(real_context);
1641  AiksContext renderer(mock_context, nullptr);
1642  std::shared_ptr<Image> image = picture.ToImage(renderer, {300, 300});
1643 
1644  ASSERT_EQ(spy->render_passes_.size(), 1llu);
1645  std::shared_ptr<RenderPass> render_pass = spy->render_passes_[0];
1646  ASSERT_EQ(render_pass->GetCommands().size(), 0llu);
1647 }

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

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

Definition at line 1689 of file aiks_unittests.cc.

1689  {
1690  Canvas canvas;
1691  canvas.DrawRect(Rect::MakeXYWH(0, 0, 300, 300),
1692  {.color = Color::Red(), .blend_mode = BlendMode::kSource});
1693  canvas.DrawRect(Rect::MakeXYWH(0, 0, 300, 300),
1694  {.color = Color::CornflowerBlue().WithAlpha(0.75),
1695  .blend_mode = BlendMode::kSourceOver});
1696 
1697  std::shared_ptr<ContextSpy> spy = ContextSpy::Make();
1698  Picture picture = canvas.EndRecordingAsPicture();
1699  std::shared_ptr<Context> real_context = GetContext();
1700  std::shared_ptr<ContextMock> mock_context = spy->MakeContext(real_context);
1701  AiksContext renderer(mock_context, nullptr);
1702  std::shared_ptr<Image> image = picture.ToImage(renderer, {301, 301});
1703 
1704  ASSERT_EQ(spy->render_passes_.size(), 1llu);
1705  std::shared_ptr<RenderPass> render_pass = spy->render_passes_[0];
1706  ASSERT_EQ(render_pass->GetCommands().size(), 2llu);
1707 }

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

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

Definition at line 1669 of file aiks_unittests.cc.

1669  {
1670  Canvas canvas;
1671  canvas.Translate(Vector3(150.0, 150.0, 0.0));
1672  canvas.Rotate(Degrees(45.0));
1673  canvas.Translate(Vector3(-150.0, -150.0, 0.0));
1674  canvas.DrawRect(Rect::MakeXYWH(0, 0, 300, 300),
1675  {.color = Color::Red(), .blend_mode = BlendMode::kSource});
1676 
1677  std::shared_ptr<ContextSpy> spy = ContextSpy::Make();
1678  Picture picture = canvas.EndRecordingAsPicture();
1679  std::shared_ptr<Context> real_context = GetContext();
1680  std::shared_ptr<ContextMock> mock_context = spy->MakeContext(real_context);
1681  AiksContext renderer(mock_context, nullptr);
1682  std::shared_ptr<Image> image = picture.ToImage(renderer, {300, 300});
1683 
1684  ASSERT_EQ(spy->render_passes_.size(), 1llu);
1685  std::shared_ptr<RenderPass> render_pass = spy->render_passes_[0];
1686  ASSERT_EQ(render_pass->GetCommands().size(), 1llu);
1687 }

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

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

Definition at line 1649 of file aiks_unittests.cc.

1649  {
1650  Canvas canvas;
1651  canvas.DrawRRect(Rect::MakeXYWH(0, 0, 300, 300), {5.0, 5.0},
1652  {.color = Color::Red(), .blend_mode = BlendMode::kSource});
1653  canvas.DrawRRect(Rect::MakeXYWH(0, 0, 300, 300), {5.0, 5.0},
1654  {.color = Color::CornflowerBlue().WithAlpha(0.75),
1655  .blend_mode = BlendMode::kSourceOver});
1656 
1657  std::shared_ptr<ContextSpy> spy = ContextSpy::Make();
1658  Picture picture = canvas.EndRecordingAsPicture();
1659  std::shared_ptr<Context> real_context = GetContext();
1660  std::shared_ptr<ContextMock> mock_context = spy->MakeContext(real_context);
1661  AiksContext renderer(mock_context, nullptr);
1662  std::shared_ptr<Image> image = picture.ToImage(renderer, {300, 300});
1663 
1664  ASSERT_EQ(spy->render_passes_.size(), 1llu);
1665  std::shared_ptr<RenderPass> render_pass = spy->render_passes_[0];
1666  ASSERT_EQ(render_pass->GetCommands().size(), 2llu);
1667 }

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

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

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

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

Definition at line 2389 of file aiks_unittests.cc.

2389  {
2390  Canvas canvas;
2391  canvas.Transform(Matrix(1.0, 0.0, 0.0, 0.0, //
2392  0.0, 1.0, 0.0, 0.0, //
2393  0.0, 0.0, 1.0, 0.01, //
2394  0.0, 0.0, 0.0, 1.0) * //
2395  Matrix::MakeRotationY({Degrees{10}}));
2396 
2397  ASSERT_TRUE(RenderTextInCanvasSkia(GetContext(), canvas, "Hello world",
2398  "Roboto-Regular.ttf"));
2399 
2400  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2401 }

References impeller::Canvas::EndRecordingAsPicture(), impeller::Matrix::MakeRotationY(), RenderTextInCanvasSkia(), and impeller::Canvas::Transform().

◆ TEST_P() [146/452]

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

Definition at line 2403 of file aiks_unittests.cc.

2403  {
2404  Canvas canvas;
2405  Paint save_paint;
2406  canvas.SaveLayer(save_paint);
2407  canvas.Transform(Matrix(1.0, 0.0, 0.0, 0.0, //
2408  0.0, 1.0, 0.0, 0.0, //
2409  0.0, 0.0, 1.0, 0.01, //
2410  0.0, 0.0, 0.0, 1.0) * //
2411  Matrix::MakeRotationY({Degrees{10}}));
2412 
2413  ASSERT_TRUE(RenderTextInCanvasSkia(GetContext(), canvas, "Hello world",
2414  "Roboto-Regular.ttf"));
2415  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2416 }

References impeller::Canvas::EndRecordingAsPicture(), impeller::Matrix::MakeRotationY(), RenderTextInCanvasSkia(), impeller::Canvas::SaveLayer(), and impeller::Canvas::Transform().

◆ TEST_P() [147/452]

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

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

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

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

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

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

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

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

Definition at line 2556 of file aiks_unittests.cc.

2556  {
2557  Canvas canvas;
2558  canvas.Scale(GetContentScale());
2559  canvas.DrawPaint(Paint{.color = Color::Red()});
2560  canvas.ClipRect(Rect::MakeXYWH(100, 100, 200, 200));
2561  canvas.SaveLayer(Paint{.color = Color::Blue()});
2562  canvas.Restore();
2563  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2564 }

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

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

Definition at line 2566 of file aiks_unittests.cc.

2566  {
2567  Canvas canvas;
2568  canvas.Scale(GetContentScale());
2569  auto image = std::make_shared<Image>(CreateTextureForFixture("airplane.jpg"));
2570  canvas.DrawImage(image, {10, 10}, {});
2571  canvas.ClipRect(Rect::MakeXYWH(100, 100, 200, 200));
2572  canvas.SaveLayer(Paint{.blend_mode = BlendMode::kClear});
2573  canvas.Restore();
2574  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2575 }

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

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

Definition at line 1249 of file aiks_unittests.cc.

1249  {
1250  Canvas canvas;
1251  canvas.Scale(GetContentScale());
1252  Paint paint;
1253  paint.mask_blur_descriptor = Paint::MaskBlurDescriptor{
1254  .style = FilterContents::BlurStyle::kNormal,
1255  .sigma = Sigma{1},
1256  };
1257 
1258  canvas.DrawPaint({.color = Color::White()});
1259 
1260  paint.color = Color::Blue();
1261  for (int i = 0; i < 5; i++) {
1262  Scalar y = i * 125;
1263  Scalar y_radius = i * 15;
1264  for (int j = 0; j < 5; j++) {
1265  Scalar x = j * 125;
1266  Scalar x_radius = j * 15;
1267  canvas.DrawRRect(Rect::MakeXYWH(x + 50, y + 50, 100.0f, 100.0f),
1268  {x_radius, y_radius}, paint);
1269  }
1270  }
1271 
1272  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1273 }

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

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

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

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

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

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

Definition at line 911 of file aiks_unittests.cc.

911  {
912  Canvas canvas;
913  canvas.Scale(GetContentScale());
914  Paint paint;
915  const int color_count = 3;
916  Color colors[color_count] = {
917  Color::Blue(),
918  Color::Green(),
919  Color::Crimson(),
920  };
921 
922  paint.color = Color::White();
923  canvas.DrawPaint(paint);
924 
925  int c_index = 0;
926  int radius = 600;
927  while (radius > 0) {
928  paint.color = colors[(c_index++) % color_count];
929  canvas.DrawCircle({10, 10}, radius, paint);
930  if (radius > 30) {
931  radius -= 10;
932  } else {
933  radius -= 2;
934  }
935  }
936 
937  std::vector<Color> gradient_colors = {
938  Color{0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0},
939  Color{0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0},
940  Color{0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0},
941  Color{0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0},
942  Color{0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0},
943  Color{0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0},
944  Color{0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0}};
945  std::vector<Scalar> stops = {
946  0.0,
947  (1.0 / 6.0) * 1,
948  (1.0 / 6.0) * 2,
949  (1.0 / 6.0) * 3,
950  (1.0 / 6.0) * 4,
951  (1.0 / 6.0) * 5,
952  1.0,
953  };
954  auto texture = CreateTextureForFixture("airplane.jpg",
955  /*enable_mipmapping=*/true);
956 
957  paint.color_source = ColorSource::MakeRadialGradient(
958  {500, 600}, 75, std::move(gradient_colors), std::move(stops),
959  Entity::TileMode::kMirror, {});
960  canvas.DrawCircle({500, 600}, 100, paint);
961 
962  paint.color_source = ColorSource::MakeImage(
963  texture, Entity::TileMode::kRepeat, Entity::TileMode::kRepeat, {},
964  Matrix::MakeTranslation({700, 200}));
965  canvas.DrawCircle({800, 300}, 100, paint);
966 
967  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
968 }

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

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

Definition at line 1034 of file aiks_unittests.cc.

1034  {
1035  Canvas canvas;
1036  canvas.Scale(GetContentScale());
1037  Paint paint;
1038  const int color_count = 3;
1039  Color colors[color_count] = {
1040  Color::Blue(),
1041  Color::Green(),
1042  Color::Crimson(),
1043  };
1044 
1045  paint.color = Color::White();
1046  canvas.DrawPaint(paint);
1047 
1048  int c_index = 0;
1049  int long_radius = 600;
1050  int short_radius = 600;
1051  while (long_radius > 0 && short_radius > 0) {
1052  paint.color = colors[(c_index++) % color_count];
1053  canvas.DrawOval(Rect::MakeXYWH(10 - long_radius, 10 - short_radius,
1054  long_radius * 2, short_radius * 2),
1055  paint);
1056  canvas.DrawOval(Rect::MakeXYWH(1000 - short_radius, 750 - long_radius,
1057  short_radius * 2, long_radius * 2),
1058  paint);
1059  if (short_radius > 30) {
1060  short_radius -= 10;
1061  long_radius -= 5;
1062  } else {
1063  short_radius -= 2;
1064  long_radius -= 1;
1065  }
1066  }
1067 
1068  std::vector<Color> gradient_colors = {
1069  Color{0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0},
1070  Color{0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0},
1071  Color{0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0},
1072  Color{0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0},
1073  Color{0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0},
1074  Color{0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0},
1075  Color{0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0}};
1076  std::vector<Scalar> stops = {
1077  0.0,
1078  (1.0 / 6.0) * 1,
1079  (1.0 / 6.0) * 2,
1080  (1.0 / 6.0) * 3,
1081  (1.0 / 6.0) * 4,
1082  (1.0 / 6.0) * 5,
1083  1.0,
1084  };
1085  auto texture = CreateTextureForFixture("airplane.jpg",
1086  /*enable_mipmapping=*/true);
1087 
1088  paint.color = Color::White().WithAlpha(0.5);
1089 
1090  paint.color_source = ColorSource::MakeRadialGradient(
1091  {300, 650}, 75, std::move(gradient_colors), std::move(stops),
1092  Entity::TileMode::kMirror, {});
1093  canvas.DrawOval(Rect::MakeXYWH(200, 625, 200, 50), paint);
1094  canvas.DrawOval(Rect::MakeXYWH(275, 550, 50, 200), paint);
1095 
1096  paint.color_source = ColorSource::MakeImage(
1097  texture, Entity::TileMode::kRepeat, Entity::TileMode::kRepeat, {},
1098  Matrix::MakeTranslation({610, 15}));
1099  canvas.DrawOval(Rect::MakeXYWH(610, 90, 200, 50), paint);
1100  canvas.DrawOval(Rect::MakeXYWH(685, 15, 50, 200), paint);
1101 
1102  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1103 }

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

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

Definition at line 1275 of file aiks_unittests.cc.

1275  {
1276  Canvas canvas;
1277  canvas.Scale(GetContentScale());
1278  Paint paint;
1279  const int color_count = 3;
1280  Color colors[color_count] = {
1281  Color::Blue(),
1282  Color::Green(),
1283  Color::Crimson(),
1284  };
1285 
1286  paint.color = Color::White();
1287  canvas.DrawPaint(paint);
1288 
1289  auto draw_rrect_as_path = [&canvas](const Rect& rect, const Size& radii,
1290  const Paint& paint) {
1291  PathBuilder builder = PathBuilder();
1292  builder.AddRoundedRect(rect, radii);
1293  canvas.DrawPath(builder.TakePath(), paint);
1294  };
1295 
1296  int c_index = 0;
1297  for (int i = 0; i < 4; i++) {
1298  for (int j = 0; j < 4; j++) {
1299  paint.color = colors[(c_index++) % color_count];
1300  draw_rrect_as_path(Rect::MakeXYWH(i * 100 + 10, j * 100 + 20, 80, 80),
1301  Size(i * 5 + 10, j * 5 + 10), paint);
1302  }
1303  }
1304  paint.color = colors[(c_index++) % color_count];
1305  draw_rrect_as_path(Rect::MakeXYWH(10, 420, 380, 80), Size(40, 40), paint);
1306  paint.color = colors[(c_index++) % color_count];
1307  draw_rrect_as_path(Rect::MakeXYWH(410, 20, 80, 380), Size(40, 40), paint);
1308 
1309  std::vector<Color> gradient_colors = {
1310  Color{0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0},
1311  Color{0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0},
1312  Color{0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0},
1313  Color{0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0},
1314  Color{0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0},
1315  Color{0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0},
1316  Color{0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0}};
1317  std::vector<Scalar> stops = {
1318  0.0,
1319  (1.0 / 6.0) * 1,
1320  (1.0 / 6.0) * 2,
1321  (1.0 / 6.0) * 3,
1322  (1.0 / 6.0) * 4,
1323  (1.0 / 6.0) * 5,
1324  1.0,
1325  };
1326  auto texture = CreateTextureForFixture("airplane.jpg",
1327  /*enable_mipmapping=*/true);
1328 
1329  paint.color = Color::White().WithAlpha(0.1);
1330  paint.color_source = ColorSource::MakeRadialGradient(
1331  {550, 550}, 75, gradient_colors, stops, Entity::TileMode::kMirror, {});
1332  for (int i = 1; i <= 10; i++) {
1333  int j = 11 - i;
1334  draw_rrect_as_path(Rect::MakeLTRB(550 - i * 20, 550 - j * 20, //
1335  550 + i * 20, 550 + j * 20),
1336  Size(i * 10, j * 10), paint);
1337  }
1338  paint.color = Color::White().WithAlpha(0.5);
1339  paint.color_source = ColorSource::MakeRadialGradient(
1340  {200, 650}, 75, std::move(gradient_colors), std::move(stops),
1341  Entity::TileMode::kMirror, {});
1342  draw_rrect_as_path(Rect::MakeLTRB(100, 610, 300, 690), Size(40, 40), paint);
1343  draw_rrect_as_path(Rect::MakeLTRB(160, 550, 240, 750), Size(40, 40), paint);
1344 
1345  paint.color = Color::White().WithAlpha(0.1);
1346  paint.color_source = ColorSource::MakeImage(
1347  texture, Entity::TileMode::kRepeat, Entity::TileMode::kRepeat, {},
1348  Matrix::MakeTranslation({520, 20}));
1349  for (int i = 1; i <= 10; i++) {
1350  int j = 11 - i;
1351  draw_rrect_as_path(Rect::MakeLTRB(720 - i * 20, 220 - j * 20, //
1352  720 + i * 20, 220 + j * 20),
1353  Size(i * 10, j * 10), paint);
1354  }
1355  paint.color = Color::White().WithAlpha(0.5);
1356  paint.color_source = ColorSource::MakeImage(
1357  texture, Entity::TileMode::kRepeat, Entity::TileMode::kRepeat, {},
1358  Matrix::MakeTranslation({800, 300}));
1359  draw_rrect_as_path(Rect::MakeLTRB(800, 410, 1000, 490), Size(40, 40), paint);
1360  draw_rrect_as_path(Rect::MakeLTRB(860, 350, 940, 550), Size(40, 40), paint);
1361 
1362  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1363 }

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

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

Definition at line 1105 of file aiks_unittests.cc.

1105  {
1106  Canvas canvas;
1107  canvas.Scale(GetContentScale());
1108  Paint paint;
1109  const int color_count = 3;
1110  Color colors[color_count] = {
1111  Color::Blue(),
1112  Color::Green(),
1113  Color::Crimson(),
1114  };
1115 
1116  paint.color = Color::White();
1117  canvas.DrawPaint(paint);
1118 
1119  int c_index = 0;
1120  for (int i = 0; i < 4; i++) {
1121  for (int j = 0; j < 4; j++) {
1122  paint.color = colors[(c_index++) % color_count];
1123  canvas.DrawRRect(Rect::MakeXYWH(i * 100 + 10, j * 100 + 20, 80, 80),
1124  Size(i * 5 + 10, j * 5 + 10), paint);
1125  }
1126  }
1127  paint.color = colors[(c_index++) % color_count];
1128  canvas.DrawRRect(Rect::MakeXYWH(10, 420, 380, 80), Size(40, 40), paint);
1129  paint.color = colors[(c_index++) % color_count];
1130  canvas.DrawRRect(Rect::MakeXYWH(410, 20, 80, 380), Size(40, 40), paint);
1131 
1132  std::vector<Color> gradient_colors = {
1133  Color{0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0},
1134  Color{0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0},
1135  Color{0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0},
1136  Color{0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0},
1137  Color{0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0},
1138  Color{0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0},
1139  Color{0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0}};
1140  std::vector<Scalar> stops = {
1141  0.0,
1142  (1.0 / 6.0) * 1,
1143  (1.0 / 6.0) * 2,
1144  (1.0 / 6.0) * 3,
1145  (1.0 / 6.0) * 4,
1146  (1.0 / 6.0) * 5,
1147  1.0,
1148  };
1149  auto texture = CreateTextureForFixture("airplane.jpg",
1150  /*enable_mipmapping=*/true);
1151 
1152  paint.color = Color::White().WithAlpha(0.1);
1153  paint.color_source = ColorSource::MakeRadialGradient(
1154  {550, 550}, 75, gradient_colors, stops, Entity::TileMode::kMirror, {});
1155  for (int i = 1; i <= 10; i++) {
1156  int j = 11 - i;
1157  canvas.DrawRRect(Rect::MakeLTRB(550 - i * 20, 550 - j * 20, //
1158  550 + i * 20, 550 + j * 20),
1159  Size(i * 10, j * 10), paint);
1160  }
1161  paint.color = Color::White().WithAlpha(0.5);
1162  paint.color_source = ColorSource::MakeRadialGradient(
1163  {200, 650}, 75, std::move(gradient_colors), std::move(stops),
1164  Entity::TileMode::kMirror, {});
1165  canvas.DrawRRect(Rect::MakeLTRB(100, 610, 300, 690), Size(40, 40), paint);
1166  canvas.DrawRRect(Rect::MakeLTRB(160, 550, 240, 750), Size(40, 40), paint);
1167 
1168  paint.color = Color::White().WithAlpha(0.1);
1169  paint.color_source = ColorSource::MakeImage(
1170  texture, Entity::TileMode::kRepeat, Entity::TileMode::kRepeat, {},
1171  Matrix::MakeTranslation({520, 20}));
1172  for (int i = 1; i <= 10; i++) {
1173  int j = 11 - i;
1174  canvas.DrawRRect(Rect::MakeLTRB(720 - i * 20, 220 - j * 20, //
1175  720 + i * 20, 220 + j * 20),
1176  Size(i * 10, j * 10), paint);
1177  }
1178  paint.color = Color::White().WithAlpha(0.5);
1179  paint.color_source = ColorSource::MakeImage(
1180  texture, Entity::TileMode::kRepeat, Entity::TileMode::kRepeat, {},
1181  Matrix::MakeTranslation({800, 300}));
1182  canvas.DrawRRect(Rect::MakeLTRB(800, 410, 1000, 490), Size(40, 40), paint);
1183  canvas.DrawRRect(Rect::MakeLTRB(860, 350, 940, 550), Size(40, 40), paint);
1184 
1185  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1186 }

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

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

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

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

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

Definition at line 864 of file aiks_unittests.cc.

864  {
865  PixelFormat pixel_format =
866  GetContext()->GetCapabilities()->GetDefaultColorFormat();
867  EXPECT_TRUE(pixel_format == PixelFormat::kR8G8B8A8UNormInt ||
868  pixel_format == PixelFormat::kB8G8R8A8UNormInt)
869  << "pixel format: " << PixelFormatToString(pixel_format);
870 }

References impeller::kB8G8R8A8UNormInt, impeller::kR8G8B8A8UNormInt, and impeller::PixelFormatToString().

◆ TEST_P() [169/452]

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

Definition at line 859 of file aiks_unittests.cc.

859  {
860  EXPECT_EQ(GetContext()->GetCapabilities()->GetDefaultColorFormat(),
861  PixelFormat::kB10G10R10A10XR);
862 }

References impeller::kB10G10R10A10XR.

◆ TEST_P() [170/452]

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Definition at line 2599 of file aiks_unittests.cc.

2599  {
2600  // Compare with https://fiddle.skia.org/c/6cdc5aefb291fda3833b806ca347a885
2601 
2602  Canvas canvas;
2603  auto texture = CreateTextureForFixture("monkey.png");
2604 
2605  canvas.DrawPaint({.color = Color::White()});
2606 
2607  // Translation
2608  {
2609  Paint paint;
2610  paint.color_source = ColorSource::MakeImage(
2611  texture, Entity::TileMode::kRepeat, Entity::TileMode::kRepeat, {},
2612  Matrix::MakeTranslation({50, 50}));
2613  canvas.DrawRect(Rect::MakeLTRB(0, 0, 100, 100), paint);
2614  }
2615 
2616  // Rotation/skew
2617  {
2618  canvas.Save();
2619  canvas.Rotate(Degrees(45));
2620  Paint paint;
2621  paint.color_source = ColorSource::MakeImage(
2622  texture, Entity::TileMode::kRepeat, Entity::TileMode::kRepeat, {},
2623  Matrix(1, -1, 0, 0, //
2624  1, 1, 0, 0, //
2625  0, 0, 1, 0, //
2626  0, 0, 0, 1) //
2627  );
2628  canvas.DrawRect(Rect::MakeLTRB(100, 0, 200, 100), paint);
2629  canvas.Restore();
2630  }
2631 
2632  // Scale
2633  {
2634  canvas.Translate(Vector2(100, 0));
2635  canvas.Scale(Vector2(100, 100));
2636  Paint paint;
2637  paint.color_source = ColorSource::MakeImage(
2638  texture, Entity::TileMode::kRepeat, Entity::TileMode::kRepeat, {},
2639  Matrix::MakeScale(Vector2(0.005, 0.005)));
2640  canvas.DrawRect(Rect::MakeLTRB(0, 0, 1, 1), paint);
2641  }
2642 
2643  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2644 }

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

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

Definition at line 1898 of file aiks_unittests.cc.

1898  {
1899  Canvas canvas;
1900  canvas.Scale(GetContentScale());
1901 
1902  auto test = [&canvas](const std::shared_ptr<ImageFilter>& filter) {
1903  auto DrawLine = [&canvas](const Point& p0, const Point& p1,
1904  const Paint& p) {
1905  auto path = PathBuilder{}
1906  .AddLine(p0, p1)
1907  .SetConvexity(Convexity::kConvex)
1908  .TakePath();
1909  Paint paint = p;
1910  paint.style = Paint::Style::kStroke;
1911  canvas.DrawPath(path, paint);
1912  };
1913  // Registration marks for the edge of the SaveLayer
1914  DrawLine(Point(75, 100), Point(225, 100), {.color = Color::White()});
1915  DrawLine(Point(75, 200), Point(225, 200), {.color = Color::White()});
1916  DrawLine(Point(100, 75), Point(100, 225), {.color = Color::White()});
1917  DrawLine(Point(200, 75), Point(200, 225), {.color = Color::White()});
1918 
1919  canvas.SaveLayer({.image_filter = filter},
1920  Rect::MakeLTRB(100, 100, 200, 200));
1921  {
1922  // DrawPaint to verify correct behavior when the contents are unbounded.
1923  canvas.DrawPaint({.color = Color::Yellow()});
1924 
1925  // Contrasting rectangle to see interior blurring
1926  canvas.DrawRect(Rect::MakeLTRB(125, 125, 175, 175),
1927  {.color = Color::Blue()});
1928  }
1929  canvas.Restore();
1930  };
1931 
1932  test(ImageFilter::MakeBlur(Sigma{10.0}, Sigma{10.0},
1933  FilterContents::BlurStyle::kNormal,
1934  Entity::TileMode::kDecal));
1935 
1936  canvas.Translate({200.0, 0.0});
1937 
1938  test(ImageFilter::MakeDilate(Radius{10.0}, Radius{10.0}));
1939 
1940  canvas.Translate({200.0, 0.0});
1941 
1942  test(ImageFilter::MakeErode(Radius{10.0}, Radius{10.0}));
1943 
1944  canvas.Translate({-400.0, 200.0});
1945 
1946  auto rotate_filter =
1947  ImageFilter::MakeMatrix(Matrix::MakeTranslation({150, 150}) *
1948  Matrix::MakeRotationZ(Degrees{10.0}) *
1949  Matrix::MakeTranslation({-150, -150}),
1950  SamplerDescriptor{});
1951  test(rotate_filter);
1952 
1953  canvas.Translate({200.0, 0.0});
1954 
1955  auto rgb_swap_filter = ImageFilter::MakeFromColorFilter(
1956  *ColorFilter::MakeMatrix({.array = {
1957  0, 1, 0, 0, 0, //
1958  0, 0, 1, 0, 0, //
1959  1, 0, 0, 0, 0, //
1960  0, 0, 0, 1, 0 //
1961  }}));
1962  test(rgb_swap_filter);
1963 
1964  canvas.Translate({200.0, 0.0});
1965 
1966  test(ImageFilter::MakeCompose(*rotate_filter, *rgb_swap_filter));
1967 
1968  canvas.Translate({-400.0, 200.0});
1969 
1970  test(ImageFilter::MakeLocalMatrix(Matrix::MakeTranslation({25.0, 25.0}),
1971  *rotate_filter));
1972 
1973  canvas.Translate({200.0, 0.0});
1974 
1975  test(ImageFilter::MakeLocalMatrix(Matrix::MakeTranslation({25.0, 25.0}),
1976  *rgb_swap_filter));
1977 
1978  canvas.Translate({200.0, 0.0});
1979 
1980  test(ImageFilter::MakeLocalMatrix(
1981  Matrix::MakeTranslation({25.0, 25.0}),
1982  *ImageFilter::MakeCompose(*rotate_filter, *rgb_swap_filter)));
1983 
1984  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1985 }

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

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

Definition at line 1987 of file aiks_unittests.cc.

1987  {
1988  Canvas canvas;
1989  canvas.Scale(GetContentScale());
1990 
1991  auto blur_filter = ImageFilter::MakeBlur(Sigma{10.0}, Sigma{10.0},
1992  FilterContents::BlurStyle::kNormal,
1993  Entity::TileMode::kDecal);
1994 
1995  canvas.SaveLayer({.image_filter = blur_filter}, std::nullopt);
1996  {
1997  // DrawPaint to verify correct behavior when the contents are unbounded.
1998  canvas.DrawPaint({.color = Color::Yellow()});
1999 
2000  // Contrasting rectangle to see interior blurring
2001  canvas.DrawRect(Rect::MakeLTRB(125, 125, 175, 175),
2002  {.color = Color::Blue()});
2003  }
2004  canvas.Restore();
2005 
2006  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2007 }

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

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

Definition at line 1808 of file aiks_unittests.cc.

1808  {
1809  Canvas canvas;
1810 
1811  canvas.SaveLayer({
1812  .color_filter = ColorFilter::MakeLinearToSrgb(),
1813  });
1814 
1815  canvas.Translate({500, 300, 0});
1816  canvas.Rotate(Radians(2 * kPi / 3));
1817  canvas.DrawRect(Rect::MakeXYWH(100, 100, 200, 200), {.color = Color::Blue()});
1818 
1819  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1820 }

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

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

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

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

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

Definition at line 2354 of file aiks_unittests.cc.

2354  {
2355  Canvas canvas;
2356  canvas.DrawPaint({.color = Color::Black()});
2357  canvas.SaveLayer({}, std::nullopt);
2358  {
2359  canvas.DrawCircle(Point(200, 200), 100,
2360  {.color = Color::Green().WithAlpha(0.5),
2361  .blend_mode = BlendMode::kPlus});
2362  // Should render a second circle, centered on the bottom-right-most edge of
2363  // the circle.
2364  canvas.SaveLayer(
2365  {}, std::nullopt,
2366  ImageFilter::MakeMatrix(
2367  Matrix::MakeTranslation(Vector2(1, 1) * (100 + 100 * k1OverSqrt2)) *
2368  Matrix::MakeScale(Vector2(1, 1) * 0.5) *
2369  Matrix::MakeTranslation(Vector2(-100, -100)),
2370  SamplerDescriptor{}));
2371  canvas.Restore();
2372  }
2373  canvas.Restore();
2374 
2375  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2376 }

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

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

Definition at line 2518 of file aiks_unittests.cc.

2519  {
2520  Canvas canvas;
2521  canvas.Scale(GetContentScale());
2522  canvas.Translate({100, 100});
2523  // Draw a circle in a SaveLayer at -300, but move it back on-screen with a
2524  // +300 translation applied by a SaveLayer image filter.
2525  canvas.SaveLayer({
2526  .image_filter = std::make_shared<MatrixImageFilter>(
2527  Matrix::MakeTranslation({300, 0}) * Matrix::MakeScale({2, 2, 2}),
2528  SamplerDescriptor{}),
2529  });
2530  canvas.DrawCircle({-150, 0}, 50, {.color = Color::Green()});
2531  canvas.Restore();
2532 
2533  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2534 }

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

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

Definition at line 2501 of file aiks_unittests.cc.

2501  {
2502  Canvas canvas;
2503  canvas.Scale(GetContentScale());
2504  canvas.Translate({100, 100});
2505  // Draw a circle in a SaveLayer at -300, but move it back on-screen with a
2506  // +300 translation applied by a SaveLayer image filter.
2507  canvas.SaveLayer({
2508  .image_filter = std::make_shared<MatrixImageFilter>(
2509  Matrix::MakeTranslation({300, 0}), SamplerDescriptor{}),
2510  });
2511  canvas.DrawCircle({-300, 0}, 100, {.color = Color::Green()});
2512  canvas.Restore();
2513 
2514  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2515 }

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

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

Definition at line 2474 of file aiks_unittests.cc.

2474  {
2475  Scalar scale = 2.0;
2476  auto callback = [&](AiksContext& renderer) -> std::optional<Picture> {
2477  if (AiksTest::ImGuiBegin("Controls", nullptr,
2478  ImGuiWindowFlags_AlwaysAutoResize)) {
2479  ImGui::SliderFloat("Scale", &scale, 1, 2);
2480  ImGui::End();
2481  }
2482  Canvas canvas;
2483  canvas.Scale(GetContentScale());
2484  auto image =
2485  std::make_shared<Image>(CreateTextureForFixture("airplane.jpg"));
2486  canvas.Translate({600, -200});
2487  canvas.SaveLayer({
2488  .image_filter = std::make_shared<MatrixImageFilter>(
2489  Matrix::MakeScale({scale, scale, 1}), SamplerDescriptor{}),
2490  });
2491  canvas.DrawImage(image, {0, 0},
2492  Paint{.color = Color::White().WithAlpha(0.5)});
2493  canvas.Restore();
2494  return canvas.EndRecordingAsPicture();
2495  };
2496 
2497  ASSERT_TRUE(OpenPlaygroundHere(callback));
2498 }

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

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

Definition at line 2327 of file aiks_unittests.cc.

2327  {
2328  Canvas canvas;
2329  canvas.DrawPaint({.color = Color::Black()});
2330  canvas.SaveLayer({}, std::nullopt);
2331  {
2332  canvas.DrawCircle(Point(200, 200), 100,
2333  {.color = Color::Green().WithAlpha(0.5),
2334  .blend_mode = BlendMode::kPlus});
2335  // Should render a second circle, centered on the bottom-right-most edge of
2336  // the circle.
2337  canvas.SaveLayer({.image_filter = ImageFilter::MakeMatrix(
2338  Matrix::MakeTranslation(Vector2(1, 1) *
2339  (200 + 100 * k1OverSqrt2)) *
2340  Matrix::MakeScale(Vector2(1, 1) * 0.5) *
2341  Matrix::MakeTranslation(Vector2(-200, -200)),
2342  SamplerDescriptor{})},
2343  std::nullopt);
2344  canvas.DrawCircle(Point(200, 200), 100,
2345  {.color = Color::Green().WithAlpha(0.5),
2346  .blend_mode = BlendMode::kPlus});
2347  canvas.Restore();
2348  }
2349  canvas.Restore();
2350 
2351  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2352 }

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

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

Definition at line 2773 of file aiks_unittests.cc.

2773  {
2774  TextureDescriptor texture_descriptor;
2775  texture_descriptor.size = ISize{1024, 1024};
2776  texture_descriptor.format = PixelFormat::kR8G8B8A8UNormInt;
2777  texture_descriptor.storage_mode = StorageMode::kHostVisible;
2778  texture_descriptor.mip_count = texture_descriptor.size.MipCount();
2779 
2780  std::vector<uint8_t> bytes(4194304);
2781  bool alternate = false;
2782  for (auto i = 0u; i < 4194304; i += 4) {
2783  if (alternate) {
2784  bytes[i] = 255;
2785  bytes[i + 1] = 0;
2786  bytes[i + 2] = 0;
2787  bytes[i + 3] = 255;
2788  } else {
2789  bytes[i] = 0;
2790  bytes[i + 1] = 255;
2791  bytes[i + 2] = 0;
2792  bytes[i + 3] = 255;
2793  }
2794  alternate = !alternate;
2795  }
2796 
2797  ASSERT_EQ(texture_descriptor.GetByteSizeOfBaseMipLevel(), bytes.size());
2798  auto mapping = std::make_shared<fml::NonOwnedMapping>(
2799  bytes.data(), // data
2800  texture_descriptor.GetByteSizeOfBaseMipLevel() // size
2801  );
2802  auto texture =
2803  GetContext()->GetResourceAllocator()->CreateTexture(texture_descriptor);
2804 
2805  auto device_buffer =
2806  GetContext()->GetResourceAllocator()->CreateBufferWithCopy(*mapping);
2807  auto command_buffer = GetContext()->CreateCommandBuffer();
2808  auto blit_pass = command_buffer->CreateBlitPass();
2809 
2810  blit_pass->AddCopy(DeviceBuffer::AsBufferView(std::move(device_buffer)),
2811  texture);
2812  blit_pass->GenerateMipmap(texture);
2813  EXPECT_TRUE(blit_pass->EncodeCommands(GetContext()->GetResourceAllocator()));
2814  EXPECT_TRUE(GetContext()->GetCommandQueue()->Submit({command_buffer}).ok());
2815 
2816  auto image = std::make_shared<Image>(texture);
2817 
2818  Canvas canvas;
2819  canvas.DrawImageRect(image, Rect::MakeSize(texture->GetSize()),
2820  Rect::MakeLTRB(0, 0, 100, 100), {});
2821 
2822  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2823 }

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

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

Definition at line 2125 of file aiks_unittests.cc.

2125  {
2126  Canvas canvas;
2127  canvas.Scale(Vector2(1.618, 1.618));
2128  canvas.DrawCircle(Point(), 10,
2129  {
2130  .color = Color::CornflowerBlue(),
2131  .blend_mode = BlendMode::kSourceOver,
2132  });
2133  Picture picture = canvas.EndRecordingAsPicture();
2134 
2135  // Extract the SolidColorSource.
2136  // Entity entity;
2137  std::vector<Entity> entity;
2138  std::shared_ptr<SolidColorContents> contents;
2139  picture.pass->IterateAllEntities([e = &entity, &contents](Entity& entity) {
2140  if (ScalarNearlyEqual(entity.GetTransform().GetScale().x, 1.618f)) {
2141  contents =
2142  std::static_pointer_cast<SolidColorContents>(entity.GetContents());
2143  e->emplace_back(entity.Clone());
2144  return false;
2145  }
2146  return true;
2147  });
2148 
2149  ASSERT_TRUE(entity.size() >= 1);
2150  ASSERT_TRUE(contents->IsOpaque());
2151  ASSERT_EQ(entity[0].GetBlendMode(), BlendMode::kSource);
2152 }

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

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

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

Definition at line 1555 of file aiks_unittests.cc.

1555  {
1556  // validate that a paint with a color filter "HasFilters", no other filters
1557  // impact this setting.
1558  Paint paint;
1559 
1560  ASSERT_FALSE(paint.HasColorFilter());
1561 
1562  paint.color_filter =
1563  ColorFilter::MakeBlend(BlendMode::kSourceOver, Color::Blue());
1564 
1565  ASSERT_TRUE(paint.HasColorFilter());
1566 
1567  paint.image_filter = ImageFilter::MakeBlur(Sigma(1.0), Sigma(1.0),
1568  FilterContents::BlurStyle::kNormal,
1569  Entity::TileMode::kClamp);
1570 
1571  ASSERT_TRUE(paint.HasColorFilter());
1572 
1573  paint.mask_blur_descriptor = {};
1574 
1575  ASSERT_TRUE(paint.HasColorFilter());
1576 
1577  paint.color_filter = nullptr;
1578 
1579  ASSERT_FALSE(paint.HasColorFilter());
1580 }

References impeller::Color::Blue(), impeller::Entity::kClamp, impeller::FilterContents::kNormal, impeller::kSourceOver, impeller::ColorFilter::MakeBlend(), impeller::ImageFilter::MakeBlur(), and paint.

◆ TEST_P() [211/452]

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

Definition at line 1606 of file aiks_unittests.cc.

1607  {
1608  Canvas canvas;
1609  canvas.SaveLayer({}, std::nullopt, ImageFilter::MakeMatrix(Matrix(), {}));
1610  canvas.DrawPaint({.color = Color::Red(), .blend_mode = BlendMode::kSource});
1611  canvas.DrawPaint({.color = Color::CornflowerBlue().WithAlpha(0.75),
1612  .blend_mode = BlendMode::kSourceOver});
1613  canvas.Restore();
1614 
1615  Picture picture = canvas.EndRecordingAsPicture();
1616 
1617  std::shared_ptr<ContextSpy> spy = ContextSpy::Make();
1618  std::shared_ptr<Context> real_context = GetContext();
1619  std::shared_ptr<ContextMock> mock_context = spy->MakeContext(real_context);
1620  AiksContext renderer(mock_context, nullptr);
1621  std::shared_ptr<Image> image = picture.ToImage(renderer, {300, 300});
1622 
1623  ASSERT_EQ(spy->render_passes_.size(),
1624  GetBackend() == PlaygroundBackend::kOpenGLES ? 4llu : 3llu);
1625  std::shared_ptr<RenderPass> render_pass = spy->render_passes_[0];
1626  ASSERT_EQ(render_pass->GetCommands().size(), 0llu);
1627 }

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

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

Definition at line 2418 of file aiks_unittests.cc.

2418  {
2419  Canvas canvas;
2420 
2421  // Should render a green square in the middle of a blue circle.
2422  canvas.SaveLayer({});
2423  {
2424  canvas.Translate(Point(100, 100));
2425  canvas.DrawCircle(Point(200, 200), 200, {.color = Color::Blue()});
2426  canvas.ClipRect(Rect::MakeXYWH(100, 100, 200, 200));
2427  canvas.DrawCircle(Point(200, 200), 200,
2428  {
2429  .color = Color::Green(),
2430  .blend_mode = BlendMode::kSourceOver,
2431  .image_filter = ImageFilter::MakeFromColorFilter(
2432  *ColorFilter::MakeBlend(BlendMode::kDestination,
2433  Color::White())),
2434  });
2435  canvas.Restore();
2436  }
2437 
2438  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2439 }

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

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

Definition at line 2442 of file aiks_unittests.cc.

2442  {
2443  auto context = MakeContext();
2444  std::weak_ptr<Texture> weak_texture;
2445 
2446  {
2447  auto texture = CreateTextureForFixture("table_mountain_nx.png");
2448 
2449  Canvas canvas;
2450  canvas.Scale(GetContentScale());
2451  canvas.Translate({100.0f, 100.0f, 0});
2452 
2453  Paint paint;
2454  paint.color_source = ColorSource::MakeImage(
2455  texture, Entity::TileMode::kClamp, Entity::TileMode::kClamp, {}, {});
2456  canvas.DrawRect(Rect::MakeXYWH(0, 0, 600, 600), paint);
2457 
2458  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2459  }
2460 
2461  // See https://github.com/flutter/flutter/issues/134751.
2462  //
2463  // If the fence waiter was working this may not be released by the end of the
2464  // scope above. Adding a manual shutdown so that future changes to the fence
2465  // waiter will not flake this test.
2466  context->Shutdown();
2467 
2468  // The texture should be released by now.
2469  ASSERT_TRUE(weak_texture.expired()) << "When the texture is no longer in use "
2470  "by the backend, it should be "
2471  "released.";
2472 }

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

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

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

Definition at line 1403 of file aiks_unittests.cc.

1403  {
1404  // Compare with https://fiddle.skia.org/c/9e03de8567ffb49e7e83f53b64bcf636
1405  Canvas canvas;
1406  Paint paint;
1407 
1408  paint.color = Color::Black();
1409  Rect rect = Rect::MakeXYWH(25, 25, 25, 25);
1410  canvas.DrawRect(rect, paint);
1411 
1412  canvas.Translate({10, 10});
1413  canvas.SaveLayer({});
1414 
1415  paint.color = Color::Green();
1416  canvas.DrawRect(rect, paint);
1417 
1418  canvas.Restore();
1419 
1420  canvas.Translate({10, 10});
1421  paint.color = Color::Red();
1422  canvas.DrawRect(rect, paint);
1423 
1424  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1425 }

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

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

Definition at line 1484 of file aiks_unittests.cc.

1484  {
1485  Canvas canvas;
1486  canvas.Scale(GetContentScale());
1487  canvas.Translate(Vector2(100, 100));
1488 
1489  auto texture = std::make_shared<Image>(CreateTextureForFixture("boston.jpg"));
1490  auto draw_image_layer = [&canvas, &texture](const Paint& paint) {
1491  canvas.SaveLayer(paint);
1492  canvas.DrawImage(texture, {}, Paint{});
1493  canvas.Restore();
1494  };
1495 
1496  Paint effect_paint;
1497  effect_paint.mask_blur_descriptor = Paint::MaskBlurDescriptor{
1498  .style = FilterContents::BlurStyle::kNormal,
1499  .sigma = Sigma{6},
1500  };
1501  draw_image_layer(effect_paint);
1502 
1503  canvas.Translate(Vector2(300, 300));
1504  canvas.Scale(Vector2(3, 3));
1505  draw_image_layer(effect_paint);
1506 
1507  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1508 }

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

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

Definition at line 2866 of file aiks_unittests.cc.

2866  {
2867  auto bridge = CreateTextureForFixture("bay_bridge.jpg");
2868 
2869  // Replace part of the texture with a red rectangle.
2870  std::vector<uint8_t> bytes(100 * 100 * 4);
2871  for (auto i = 0u; i < bytes.size(); i += 4) {
2872  bytes[i] = 255;
2873  bytes[i + 1] = 0;
2874  bytes[i + 2] = 0;
2875  bytes[i + 3] = 255;
2876  }
2877  auto mapping =
2878  std::make_shared<fml::NonOwnedMapping>(bytes.data(), bytes.size());
2879  auto device_buffer =
2880  GetContext()->GetResourceAllocator()->CreateBufferWithCopy(*mapping);
2881  auto cmd_buffer = GetContext()->CreateCommandBuffer();
2882  auto blit_pass = cmd_buffer->CreateBlitPass();
2883  blit_pass->AddCopy(DeviceBuffer::AsBufferView(device_buffer), bridge,
2884  IRect::MakeLTRB(50, 50, 150, 150));
2885 
2886  auto did_submit =
2887  blit_pass->EncodeCommands(GetContext()->GetResourceAllocator()) &&
2888  GetContext()->GetCommandQueue()->Submit({std::move(cmd_buffer)}).ok();
2889  ASSERT_TRUE(did_submit);
2890 
2891  auto image = std::make_shared<Image>(bridge);
2892 
2893  Canvas canvas;
2894  canvas.DrawImage(image, {0, 0}, {});
2895 
2896  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2897 }

References impeller::DeviceBuffer::AsBufferView(), impeller::Canvas::DrawImage(), impeller::Canvas::EndRecordingAsPicture(), and impeller::TRect< T >::MakeLTRB().

◆ TEST_P() [218/452]

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

Definition at line 1427 of file aiks_unittests.cc.

1427  {
1428  Canvas canvas;
1429  Paint paint;
1430  Rect rect = Rect::MakeXYWH(0, 0, 1000, 1000);
1431 
1432  // Black, green, and red squares offset by [10, 10].
1433  {
1434  canvas.SaveLayer({}, Rect::MakeXYWH(25, 25, 25, 25));
1435  paint.color = Color::Black();
1436  canvas.DrawRect(rect, paint);
1437  canvas.Restore();
1438  }
1439 
1440  {
1441  canvas.SaveLayer({}, Rect::MakeXYWH(35, 35, 25, 25));
1442  paint.color = Color::Green();
1443  canvas.DrawRect(rect, paint);
1444  canvas.Restore();
1445  }
1446 
1447  {
1448  canvas.SaveLayer({}, Rect::MakeXYWH(45, 45, 25, 25));
1449  paint.color = Color::Red();
1450  canvas.DrawRect(rect, paint);
1451  canvas.Restore();
1452  }
1453 
1454  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1455 }

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

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

Definition at line 2378 of file aiks_unittests.cc.

2378  {
2379  auto contents = SolidColorContents();
2380  contents.SetColor(Color::CornflowerBlue().WithAlpha(0.75));
2381  auto result = contents.ApplyColorFilter([](const Color& color) {
2382  return color.Blend(Color::LimeGreen().WithAlpha(0.75), BlendMode::kScreen);
2383  });
2384  ASSERT_TRUE(result);
2385  ASSERT_COLOR_NEAR(contents.GetColor(),
2386  Color(0.424452, 0.828743, 0.79105, 0.9375));
2387 }

References ASSERT_COLOR_NEAR, color, impeller::Color::CornflowerBlue(), impeller::kScreen, and impeller::Color::LimeGreen().

◆ TEST_P() [220/452]

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

Definition at line 1188 of file aiks_unittests.cc.

1188  {
1189  Canvas canvas;
1190  canvas.Scale(GetContentScale());
1191  Paint paint;
1192  paint.mask_blur_descriptor = Paint::MaskBlurDescriptor{
1193  .style = FilterContents::BlurStyle::kNormal,
1194  .sigma = Sigma{1},
1195  };
1196 
1197  canvas.DrawPaint({.color = Color::White()});
1198 
1199  paint.color = Color::Crimson();
1200  Scalar y = 100.0f;
1201  for (int i = 0; i < 5; i++) {
1202  Scalar x = (i + 1) * 100;
1203  Scalar radius = x / 10.0f;
1204  canvas.DrawRect(Rect::MakeXYWH(x + 25 - radius / 2, y + radius / 2, //
1205  radius, 60.0f - radius),
1206  paint);
1207  }
1208 
1209  paint.color = Color::Blue();
1210  y += 100.0f;
1211  for (int i = 0; i < 5; i++) {
1212  Scalar x = (i + 1) * 100;
1213  Scalar radius = x / 10.0f;
1214  canvas.DrawCircle({x + 25, y + 25}, radius, paint);
1215  }
1216 
1217  paint.color = Color::Green();
1218  y += 100.0f;
1219  for (int i = 0; i < 5; i++) {
1220  Scalar x = (i + 1) * 100;
1221  Scalar radius = x / 10.0f;
1222  canvas.DrawOval(Rect::MakeXYWH(x + 25 - radius / 2, y + radius / 2, //
1223  radius, 60.0f - radius),
1224  paint);
1225  }
1226 
1227  paint.color = Color::Purple();
1228  y += 100.0f;
1229  for (int i = 0; i < 5; i++) {
1230  Scalar x = (i + 1) * 100;
1231  Scalar radius = x / 20.0f;
1232  canvas.DrawRRect(Rect::MakeXYWH(x, y, 60.0f, 60.0f), //
1233  {radius, radius}, //
1234  paint);
1235  }
1236 
1237  paint.color = Color::Orange();
1238  y += 100.0f;
1239  for (int i = 0; i < 5; i++) {
1240  Scalar x = (i + 1) * 100;
1241  Scalar radius = x / 20.0f;
1242  canvas.DrawRRect(Rect::MakeXYWH(x, y, 60.0f, 60.0f), //
1243  {radius, 5.0f}, paint);
1244  }
1245 
1246  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1247 }

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

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

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

Definition at line 1822 of file aiks_unittests.cc.

1822  {
1823  Canvas canvas;
1824 
1825  canvas.SaveLayer({
1826  .color_filter = ColorFilter::MakeSrgbToLinear(),
1827  });
1828 
1829  canvas.Translate({500, 300, 0});
1830  canvas.Rotate(Radians(2 * kPi / 3));
1831  canvas.DrawRect(Rect::MakeXYWH(100, 100, 200, 200), {.color = Color::Blue()});
1832 
1833  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1834 }

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

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

Definition at line 970 of file aiks_unittests.cc.

970  {
971  Canvas canvas;
972  canvas.Scale(GetContentScale());
973  Paint paint;
974  const int color_count = 3;
975  Color colors[color_count] = {
976  Color::Blue(),
977  Color::Green(),
978  Color::Crimson(),
979  };
980 
981  paint.color = Color::White();
982  canvas.DrawPaint(paint);
983 
984  int c_index = 0;
985 
986  auto draw = [&paint, &colors, &c_index](Canvas& canvas, Point center,
987  Scalar r, Scalar dr, int n) {
988  for (int i = 0; i < n; i++) {
989  paint.color = colors[(c_index++) % color_count];
990  canvas.DrawCircle(center, r, paint);
991  r += dr;
992  }
993  };
994 
995  paint.style = Paint::Style::kStroke;
996  paint.stroke_width = 1;
997  draw(canvas, {10, 10}, 2, 2, 14); // r = [2, 28], covers [1,29]
998  paint.stroke_width = 5;
999  draw(canvas, {10, 10}, 35, 10, 56); // r = [35, 585], covers [30,590]
1000 
1001  std::vector<Color> gradient_colors = {
1002  Color{0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0},
1003  Color{0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0},
1004  Color{0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0},
1005  Color{0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0},
1006  Color{0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0},
1007  Color{0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0},
1008  Color{0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0}};
1009  std::vector<Scalar> stops = {
1010  0.0,
1011  (1.0 / 6.0) * 1,
1012  (1.0 / 6.0) * 2,
1013  (1.0 / 6.0) * 3,
1014  (1.0 / 6.0) * 4,
1015  (1.0 / 6.0) * 5,
1016  1.0,
1017  };
1018  auto texture = CreateTextureForFixture("airplane.jpg",
1019  /*enable_mipmapping=*/true);
1020 
1021  paint.color_source = ColorSource::MakeRadialGradient(
1022  {500, 600}, 75, std::move(gradient_colors), std::move(stops),
1023  Entity::TileMode::kMirror, {});
1024  draw(canvas, {500, 600}, 5, 10, 10);
1025 
1026  paint.color_source = ColorSource::MakeImage(
1027  texture, Entity::TileMode::kRepeat, Entity::TileMode::kRepeat, {},
1028  Matrix::MakeTranslation({700, 200}));
1029  draw(canvas, {800, 300}, 5, 10, 10);
1030 
1031  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1032 }

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

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

Definition at line 2826 of file aiks_unittests.cc.

2826  {
2827  Path path = PathBuilder{}
2828  .MoveTo({0, 400})
2829  .LineTo({0, 0})
2830  .LineTo({400, 0})
2831  // MoveTo implicitly adds a contour, ensure that close doesn't
2832  // add another nearly-empty contour.
2833  .MoveTo({0, 400})
2834  .Close()
2835  .TakePath();
2836 
2837  Canvas canvas;
2838  canvas.Translate({50, 50, 0});
2839  canvas.DrawPath(path, {
2840  .color = Color::Blue(),
2841  .stroke_width = 10,
2842  .stroke_cap = Cap::kRound,
2843  .style = Paint::Style::kStroke,
2844  });
2845  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2846 }

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

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

Definition at line 2577 of file aiks_unittests.cc.

2577  {
2578  Canvas canvas;
2579 
2580  // Use a non-srcOver blend mode to ensure that we don't detect this as an
2581  // opacity peephole optimization.
2582  canvas.SaveLayer(
2583  {.color = Color::Blue().WithAlpha(0.5), .blend_mode = BlendMode::kSource},
2584  Rect::MakeLTRB(0, 0, 200, 200));
2585  canvas.DrawPaint(
2586  {.color = Color::BlackTransparent(), .blend_mode = BlendMode::kSource});
2587  canvas.Restore();
2588 
2589  canvas.SaveLayer(
2590  {.color = Color::Blue(), .blend_mode = BlendMode::kDestinationOver});
2591  canvas.Restore();
2592 
2593  // This playground should appear blank on CI since we are only drawing
2594  // transparent black. If the clear color optimization is broken, the texture
2595  // will be filled with NaNs and may produce a magenta texture on macOS or iOS.
2596  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2597 }

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

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

Definition at line 2294 of file aiks_unittests.cc.

2294  {
2295  auto mapping = flutter::testing::OpenFixtureAsSkData("Roboto-Regular.ttf");
2296  ASSERT_NE(mapping, nullptr);
2297 
2298  Scalar font_size = 100;
2299  sk_sp<SkFontMgr> font_mgr = txt::GetDefaultFontManager();
2300  SkFont sk_font(font_mgr->makeFromData(mapping), font_size);
2301 
2302  Paint text_paint;
2303  text_paint.color = Color::Blue();
2304 
2305  std::vector<Color> colors = {Color{0.9568, 0.2627, 0.2118, 1.0},
2306  Color{0.1294, 0.5882, 0.9529, 1.0}};
2307  std::vector<Scalar> stops = {
2308  0.0,
2309  1.0,
2310  };
2311  text_paint.color_source = ColorSource::MakeLinearGradient(
2312  {0, 0}, {100, 100}, std::move(colors), std::move(stops),
2313  Entity::TileMode::kRepeat, {});
2314 
2315  Canvas canvas;
2316  canvas.Translate({100, 100});
2317  canvas.Rotate(Radians(kPi / 4));
2318 
2319  auto blob = SkTextBlob::MakeFromString("Hello", sk_font);
2320  ASSERT_NE(blob, nullptr);
2321  auto frame = MakeTextFrameFromTextBlobSkia(blob);
2322  canvas.DrawTextFrame(frame, Point(), text_paint);
2323 
2324  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2325 }

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

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

Definition at line 672 of file aiks_unittests.cc.

672  {
673  // "Random" numbers between 0 and 1. Hardcoded to avoid flakiness in goldens.
674  std::array<Scalar, 20> phase_offsets = {
675  7.82637e-06, 0.131538, 0.755605, 0.45865, 0.532767,
676  0.218959, 0.0470446, 0.678865, 0.679296, 0.934693,
677  0.383502, 0.519416, 0.830965, 0.0345721, 0.0534616,
678  0.5297, 0.671149, 0.00769819, 0.383416, 0.0668422};
679  auto callback = [&](AiksContext& renderer) -> std::optional<Picture> {
680  static float font_size = 20;
681  static float phase_variation = 0.2;
682  static float speed = 0.5;
683  static float magnitude = 100;
684  if (AiksTest::ImGuiBegin("Controls", nullptr,
685  ImGuiWindowFlags_AlwaysAutoResize)) {
686  ImGui::SliderFloat("Font size", &font_size, 5, 50);
687  ImGui::SliderFloat("Phase variation", &phase_variation, 0, 1);
688  ImGui::SliderFloat("Oscillation speed", &speed, 0, 2);
689  ImGui::SliderFloat("Oscillation magnitude", &magnitude, 0, 300);
690  ImGui::End();
691  }
692 
693  Canvas canvas;
694  canvas.Scale(GetContentScale());
695 
696  for (size_t i = 0; i < phase_offsets.size(); i++) {
697  auto position =
698  Point(200 + magnitude *
699  std::sin((-phase_offsets[i] * k2Pi * phase_variation +
700  GetSecondsElapsed() * speed)), //
701  200 + i * font_size * 1.1 //
702  );
704  GetContext(), canvas,
705  "the quick brown fox jumped over "
706  "the lazy dog!.?",
707  "Roboto-Regular.ttf",
708  {.font_size = font_size, .position = position})) {
709  return std::nullopt;
710  }
711  }
712  return canvas.EndRecordingAsPicture();
713  };
714 
715  ASSERT_TRUE(OpenPlaygroundHere(callback));
716 }

References impeller::Canvas::EndRecordingAsPicture(), font_size, impeller::AiksPlayground::ImGuiBegin(), impeller::k2Pi, RenderTextInCanvasSkia(), and impeller::Canvas::Scale().

◆ TEST_P() [228/452]

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

Definition at line 827 of file aiks_unittests.cc.

827  {
828  Canvas canvas;
829  canvas.Scale(GetContentScale());
830  canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)});
831 
832  canvas.Transform(Matrix(0.25, -0.3, 0, -0.002, //
833  0, 0.5, 0, 0, //
834  0, 0, 0.3, 0, //
835  100, 100, 0, 1.3));
836  ASSERT_TRUE(RenderTextInCanvasSkia(
837  GetContext(), canvas, "the quick brown fox jumped over the lazy dog!.?",
838  "Roboto-Regular.ttf"));
839 
840  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
841 }

References impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), RenderTextInCanvasSkia(), impeller::Canvas::Scale(), and impeller::Canvas::Transform().

◆ TEST_P() [229/452]

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

Definition at line 872 of file aiks_unittests.cc.

872  {
873  Canvas canvas;
874  ASSERT_MATRIX_NEAR(canvas.GetCurrentTransform(), Matrix());
875 
876  // clang-format off
877  canvas.Translate(Vector3(100, 200));
879  canvas.GetCurrentTransform(),
880  Matrix( 1, 0, 0, 0,
881  0, 1, 0, 0,
882  0, 0, 1, 0,
883  100, 200, 0, 1));
884 
885  canvas.Rotate(Radians(kPiOver2));
887  canvas.GetCurrentTransform(),
888  Matrix( 0, 1, 0, 0,
889  -1, 0, 0, 0,
890  0, 0, 1, 0,
891  100, 200, 0, 1));
892 
893  canvas.Scale(Vector3(2, 3));
895  canvas.GetCurrentTransform(),
896  Matrix( 0, 2, 0, 0,
897  -3, 0, 0, 0,
898  0, 0, 0, 0,
899  100, 200, 0, 1));
900 
901  canvas.Translate(Vector3(100, 200));
903  canvas.GetCurrentTransform(),
904  Matrix( 0, 2, 0, 0,
905  -3, 0, 0, 0,
906  0, 0, 0, 0,
907  -500, 400, 0, 1));
908  // clang-format on
909 }

References ASSERT_MATRIX_NEAR, impeller::Canvas::GetCurrentTransform(), impeller::kPiOver2, impeller::Canvas::Rotate(), impeller::Canvas::Scale(), and impeller::Canvas::Translate().

◆ TEST_P() [230/452]

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

Definition at line 1836 of file aiks_unittests.cc.

1836  {
1837  Canvas canvas;
1838 
1839  canvas.DrawRect(Rect::MakeXYWH(100, 100, 300, 300), {.color = Color::Blue()});
1840 
1841  canvas.SaveLayer({.color = Color::Black().WithAlpha(0.5)});
1842  canvas.DrawRect(Rect::MakeXYWH(100, 500, 300, 300), {.color = Color::Blue()});
1843  canvas.Restore();
1844 
1845  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1846 }

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

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

Definition at line 2009 of file aiks_unittests.cc.

2009  {
2010  Canvas canvas;
2011 
2012  auto image = std::make_shared<Image>(CreateTextureForFixture("airplane.jpg"));
2013  canvas.DrawImage(image, {100, 100}, {});
2014 
2015  canvas.SaveLayer({.color = Color::Black().WithAlpha(0.5)});
2016  canvas.DrawImage(image, {100, 500}, {});
2017  canvas.Restore();
2018 
2019  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2020 }

References impeller::Color::Black(), impeller::Canvas::DrawImage(), impeller::Canvas::EndRecordingAsPicture(), impeller::Canvas::Restore(), impeller::Canvas::SaveLayer(), and impeller::Color::WithAlpha().

◆ TEST_P() [232/452]

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

Definition at line 2093 of file aiks_unittests.cc.

2093  {
2094  Canvas canvas;
2095  canvas.DrawRect(Rect::MakeXYWH(0, 0, 400, 400), {.color = Color::Red()});
2096  canvas.SaveLayer({
2097  .color = Color::Black().WithAlpha(0.5),
2098  .blend_mode = BlendMode::kLighten,
2099  });
2100  canvas.DrawCircle({200, 200}, 100, {.color = Color::Green()});
2101  canvas.Restore();
2102  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2103 }

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

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

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({
1854  .color = Color::Black().WithAlpha(0.5),
1855  .color_filter =
1856  ColorFilter::MakeBlend(BlendMode::kDestinationOver, Color::Red()),
1857  });
1858  canvas.DrawRect(Rect::MakeXYWH(100, 500, 300, 300), {.color = Color::Blue()});
1859  canvas.Restore();
1860 
1861  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1862 }

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

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

Definition at line 1864 of file aiks_unittests.cc.

1864  {
1865  Canvas canvas;
1866 
1867  canvas.DrawRect(Rect::MakeXYWH(100, 100, 300, 300), {.color = Color::Blue()});
1868 
1869  canvas.SaveLayer({
1870  .color = Color::Black().WithAlpha(0.5),
1871  .image_filter = ImageFilter::MakeFromColorFilter(
1872  *ColorFilter::MakeBlend(BlendMode::kDestinationOver, Color::Red())),
1873  });
1874 
1875  canvas.DrawRect(Rect::MakeXYWH(100, 500, 300, 300), {.color = Color::Blue()});
1876  canvas.Restore();
1877 
1878  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1879 }

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

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

Definition at line 1881 of file aiks_unittests.cc.

1881  {
1882  Canvas canvas;
1883 
1884  canvas.DrawRect(Rect::MakeXYWH(100, 100, 300, 300), {.color = Color::Blue()});
1885 
1886  canvas.SaveLayer({
1887  .color = Color::Black().WithAlpha(0.5),
1888  .color_filter =
1889  ColorFilter::MakeBlend(BlendMode::kDestinationOver, Color::Red()),
1890  });
1891 
1892  canvas.DrawRect(Rect::MakeXYWH(100, 500, 300, 300), {.color = Color::Blue()});
1893  canvas.Restore();
1894 
1895  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1896 }

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

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

Definition at line 2067 of file aiks_unittests.cc.

2068  {
2069  Canvas canvas;
2070 
2071  auto image = std::make_shared<Image>(CreateTextureForFixture("airplane.jpg"));
2072  canvas.DrawImage(image, {100, 100}, {});
2073 
2074  canvas.SaveLayer({
2075  .color = Color::Black().WithAlpha(0.5),
2076  .image_filter = ImageFilter::MakeFromColorFilter(
2077  *ColorFilter::MakeMatrix({.array =
2078  {
2079  1, 0, 0, 0, 0, //
2080  0, 1, 0, 0, 0, //
2081  0, 0.2, 1, 0, 0, //
2082  0, 0, 0, 0.5, 0 //
2083  }})),
2084  .color_filter =
2085  ColorFilter::MakeBlend(BlendMode::kModulate, Color::Green()),
2086  });
2087  canvas.DrawImage(image, {100, 500}, {});
2088  canvas.Restore();
2089 
2090  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2091 }

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

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

Definition at line 2022 of file aiks_unittests.cc.

2022  {
2023  Canvas canvas;
2024 
2025  auto image = std::make_shared<Image>(CreateTextureForFixture("airplane.jpg"));
2026  canvas.DrawImage(image, {100, 100}, {});
2027 
2028  canvas.SaveLayer({
2029  .color = Color::Black().WithAlpha(0.5),
2030  .color_filter = ColorFilter::MakeMatrix({.array =
2031  {
2032  1, 0, 0, 0, 0, //
2033  0, 1, 0, 0, 0, //
2034  0, 0, 1, 0, 0, //
2035  0, 0, 0, 2, 0 //
2036  }}),
2037  });
2038  canvas.DrawImage(image, {100, 500}, {});
2039  canvas.Restore();
2040 
2041  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2042 }

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

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

Definition at line 2044 of file aiks_unittests.cc.

2044  {
2045  Canvas canvas;
2046 
2047  auto image = std::make_shared<Image>(CreateTextureForFixture("airplane.jpg"));
2048  canvas.DrawImage(image, {100, 100}, {});
2049 
2050  canvas.SaveLayer({
2051  .color = Color::Black().WithAlpha(0.5),
2052  .image_filter = ImageFilter::MakeFromColorFilter(
2053  *ColorFilter::MakeMatrix({.array =
2054  {
2055  1, 0, 0, 0, 0, //
2056  0, 1, 0, 0, 0, //
2057  0, 0, 1, 0, 0, //
2058  0, 0, 0, 2, 0 //
2059  }})),
2060  });
2061  canvas.DrawImage(image, {100, 500}, {});
2062  canvas.Restore();
2063 
2064  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2065 }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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 728 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:798
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:728
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:845
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