Flutter Impeller
impeller::testing Namespace Reference

Classes

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

Typedefs

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

Functions

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

Variables

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

Typedef Documentation

◆ AiksTest

Definition at line 17 of file aiks_unittests.h.

◆ AllocatorMTLTest

◆ BlitPassTest

Definition at line 27 of file blit_pass_unittests.cc.

◆ ComputeTest

Definition at line 21 of file compute_unittests.cc.

◆ 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

◆ PipelineCacheDataVKPlaygroundTest

◆ RendererTest

◆ RenderTargetCacheTest

◆ RuntimeStageTest

◆ SaveLayerUtilsTest

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

Definition at line 15 of file save_layer_utils_unittests.cc.

◆ SwapchainTransientsMTLTest

◆ TextContentsTest

◆ TypographerTest

Function Documentation

◆ APPLY_COLOR_FILTER_GRADIENT_TEST() [1/4]

impeller::testing::APPLY_COLOR_FILTER_GRADIENT_TEST ( Conical  )

◆ APPLY_COLOR_FILTER_GRADIENT_TEST() [2/4]

impeller::testing::APPLY_COLOR_FILTER_GRADIENT_TEST ( Linear  )

◆ APPLY_COLOR_FILTER_GRADIENT_TEST() [3/4]

impeller::testing::APPLY_COLOR_FILTER_GRADIENT_TEST ( Radial  )

◆ APPLY_COLOR_FILTER_GRADIENT_TEST() [4/4]

impeller::testing::APPLY_COLOR_FILTER_GRADIENT_TEST ( Sweep  )

◆ BlendModeTest()

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

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

Definition at line 502 of file aiks_dl_blend_unittests.cc.

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

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

◆ CanBatchSubmitTest()

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

Definition at line 70 of file driver_info_vk_unittests.cc.

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

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

Referenced by TEST().

◆ CanRenderConicalGradientWithDithering()

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

Definition at line 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(), 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().

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(), 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(), impeller::Color::ToARGB(), impeller::TPoint< T >::x, and impeller::TPoint< T >::y.

Referenced by TEST_P().

◆ CanUseFramebufferFetch()

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

Definition at line 196 of file driver_info_vk_unittests.cc.

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

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

Referenced by TEST().

◆ CanUseMipgeneration()

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

Definition at line 126 of file driver_info_vk_unittests.cc.

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

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

Referenced by TEST().

◆ CanUsePrimitiveRestartSubmitTest()

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

Definition at line 97 of file driver_info_vk_unittests.cc.

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

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

Referenced by TEST().

◆ CAPABILITY_TEST() [1/10]

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

◆ CAPABILITY_TEST() [2/10]

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

◆ CAPABILITY_TEST() [3/10]

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

◆ CAPABILITY_TEST() [4/10]

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

◆ CAPABILITY_TEST() [5/10]

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

◆ CAPABILITY_TEST() [6/10]

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

◆ CAPABILITY_TEST() [7/10]

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

◆ CAPABILITY_TEST() [8/10]

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

◆ CAPABILITY_TEST() [9/10]

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

◆ CAPABILITY_TEST() [10/10]

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

◆ CompareFunctionUI()

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

Definition at line 1206 of file renderer_unittests.cc.

1206  {
1207  static CompareFunctionUIData data;
1208  return data;
1209 }
std::shared_ptr< const fml::Mapping > data
Definition: texture_gles.cc:64

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

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

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::shared_ptr< TextFrame > &  frame 
)
static

Definition at line 32 of file typographer_unittests.cc.

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

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

Referenced by TEST_P().

◆ CreateGlyphAtlas() [2/2]

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

Definition at line 45 of file typographer_unittests.cc.

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

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

◆ CreateMappingFromString()

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

Definition at line 15 of file shader_archive_unittests.cc.

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

Referenced by TEST().

◆ CreateStringFromMapping()

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

Definition at line 23 of file shader_archive_unittests.cc.

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

Referenced by TEST().

◆ CreateTestCanvas()

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

Definition at line 24 of file canvas_unittests.cc.

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

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

Referenced by TEST_P().

◆ CreateTestYUVTextures()

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

Definition at line 1592 of file entity_unittests.cc.

1594  {
1595  Vector3 red = {244.0 / 255.0, 67.0 / 255.0, 54.0 / 255.0};
1596  Vector3 green = {76.0 / 255.0, 175.0 / 255.0, 80.0 / 255.0};
1597  Vector3 blue = {33.0 / 255.0, 150.0 / 255.0, 243.0 / 255.0};
1598  Vector3 white = {1.0, 1.0, 1.0};
1599  Vector3 red_yuv = RGBToYUV(red, yuv_color_space);
1600  Vector3 green_yuv = RGBToYUV(green, yuv_color_space);
1601  Vector3 blue_yuv = RGBToYUV(blue, yuv_color_space);
1602  Vector3 white_yuv = RGBToYUV(white, yuv_color_space);
1603  std::vector<Vector3> yuvs{red_yuv, green_yuv, blue_yuv, white_yuv};
1604  std::vector<uint8_t> y_data;
1605  std::vector<uint8_t> uv_data;
1606  for (int i = 0; i < 4; i++) {
1607  auto yuv = yuvs[i];
1608  uint8_t y = std::round(yuv.x * 255.0);
1609  uint8_t u = std::round(yuv.y * 255.0);
1610  uint8_t v = std::round(yuv.z * 255.0);
1611  for (int j = 0; j < 16; j++) {
1612  y_data.push_back(y);
1613  }
1614  for (int j = 0; j < 8; j++) {
1615  uv_data.push_back(j % 2 == 0 ? u : v);
1616  }
1617  }
1618  auto cmd_buffer = context->CreateCommandBuffer();
1619  auto blit_pass = cmd_buffer->CreateBlitPass();
1620 
1621  impeller::TextureDescriptor y_texture_descriptor;
1622  y_texture_descriptor.storage_mode = impeller::StorageMode::kHostVisible;
1623  y_texture_descriptor.format = PixelFormat::kR8UNormInt;
1624  y_texture_descriptor.size = {8, 8};
1625  auto y_texture =
1626  context->GetResourceAllocator()->CreateTexture(y_texture_descriptor);
1627  auto y_mapping = std::make_shared<fml::DataMapping>(y_data);
1628  auto y_mapping_buffer =
1629  context->GetResourceAllocator()->CreateBufferWithCopy(*y_mapping);
1630 
1631  blit_pass->AddCopy(DeviceBuffer::AsBufferView(y_mapping_buffer), y_texture);
1632 
1633  impeller::TextureDescriptor uv_texture_descriptor;
1634  uv_texture_descriptor.storage_mode = impeller::StorageMode::kHostVisible;
1635  uv_texture_descriptor.format = PixelFormat::kR8G8UNormInt;
1636  uv_texture_descriptor.size = {4, 4};
1637  auto uv_texture =
1638  context->GetResourceAllocator()->CreateTexture(uv_texture_descriptor);
1639  auto uv_mapping = std::make_shared<fml::DataMapping>(uv_data);
1640  auto uv_mapping_buffer =
1641  context->GetResourceAllocator()->CreateBufferWithCopy(*uv_mapping);
1642 
1643  blit_pass->AddCopy(DeviceBuffer::AsBufferView(uv_mapping_buffer), uv_texture);
1644 
1645  if (!blit_pass->EncodeCommands() ||
1646  !context->GetCommandQueue()->Submit({cmd_buffer}).ok()) {
1647  FML_DLOG(ERROR) << "Could not copy contents into Y/UV texture.";
1648  }
1649 
1650  return {y_texture, uv_texture};
1651 }
static Vector3 RGBToYUV(Vector3 rgb, YUVColorSpace yuv_color_space)
A lightweight object that describes the attributes of a texture that can then used an allocator to cr...

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

Referenced by TEST_P().

◆ DoGradientOvalStrokeMaskBlur()

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

Definition at line 63 of file aiks_dl_blur_unittests.cc.

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

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

Referenced by TEST_P().

◆ flip_lr()

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

Definition at line 1324 of file rect_unittests.cc.

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

Referenced by flip_lrtb(), and TEST().

◆ flip_lrtb()

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

Definition at line 1336 of file rect_unittests.cc.

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

References flip_lr(), and flip_tb().

Referenced by TEST().

◆ flip_tb()

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

Definition at line 1330 of file rect_unittests.cc.

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

Referenced by flip_lrtb(), and TEST().

◆ FML_TEST_CLASS()

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

◆ GetBlendModeSelection()

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

Definition at line 45 of file aiks_dl_blend_unittests.cc.

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

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

Referenced by TEST_P().

◆ INSTANTIATE_COMPUTE_SUITE()

impeller::testing::INSTANTIATE_COMPUTE_SUITE ( ComputeTest  )

◆ INSTANTIATE_METAL_PLAYGROUND_SUITE()

impeller::testing::INSTANTIATE_METAL_PLAYGROUND_SUITE ( AllocatorMTLTest  )

◆ INSTANTIATE_PLAYGROUND_SUITE() [1/9]

impeller::testing::INSTANTIATE_PLAYGROUND_SUITE ( AiksTest  )

◆ INSTANTIATE_PLAYGROUND_SUITE() [2/9]

impeller::testing::INSTANTIATE_PLAYGROUND_SUITE ( BlendFilterContentsTest  )

◆ INSTANTIATE_PLAYGROUND_SUITE() [3/9]

impeller::testing::INSTANTIATE_PLAYGROUND_SUITE ( DisplayListTest  )

◆ INSTANTIATE_PLAYGROUND_SUITE() [4/9]

impeller::testing::INSTANTIATE_PLAYGROUND_SUITE ( GaussianBlurFilterContentsTest  )

◆ INSTANTIATE_PLAYGROUND_SUITE() [5/9]

impeller::testing::INSTANTIATE_PLAYGROUND_SUITE ( HostBufferTest  )

◆ INSTANTIATE_PLAYGROUND_SUITE() [6/9]

impeller::testing::INSTANTIATE_PLAYGROUND_SUITE ( MatrixFilterContentsTest  )

◆ INSTANTIATE_PLAYGROUND_SUITE() [7/9]

impeller::testing::INSTANTIATE_PLAYGROUND_SUITE ( RendererDartTest  )

◆ INSTANTIATE_PLAYGROUND_SUITE() [8/9]

impeller::testing::INSTANTIATE_PLAYGROUND_SUITE ( RuntimeStageTest  )

◆ INSTANTIATE_PLAYGROUND_SUITE() [9/9]

impeller::testing::INSTANTIATE_PLAYGROUND_SUITE ( TextContentsTest  )

◆ INSTANTIATE_VULKAN_PLAYGROUND_SUITE()

impeller::testing::INSTANTIATE_VULKAN_PLAYGROUND_SUITE ( DriverInfoVKTest  )

◆ InstantiateTestShaderLibrary()

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

Definition at line 34 of file renderer_dart_unittests.cc.

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

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

◆ IsBadVersionTest()

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

Definition at line 52 of file driver_info_vk_unittests.cc.

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

Referenced by TEST().

◆ MaskBlurVariantTest()

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

Definition at line 506 of file aiks_dl_blur_unittests.cc.

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

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

◆ RenderTextInCanvasSkia()

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

Definition at line 42 of file aiks_dl_text_unittests.cc.

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

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

◆ RGBToYUV()

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

Definition at line 1575 of file entity_unittests.cc.

1575  {
1576  Vector3 yuv;
1577  switch (yuv_color_space) {
1578  case YUVColorSpace::kBT601FullRange:
1579  yuv.x = rgb.x * 0.299 + rgb.y * 0.587 + rgb.z * 0.114;
1580  yuv.y = rgb.x * -0.169 + rgb.y * -0.331 + rgb.z * 0.5 + 0.5;
1581  yuv.z = rgb.x * 0.5 + rgb.y * -0.419 + rgb.z * -0.081 + 0.5;
1582  break;
1583  case YUVColorSpace::kBT601LimitedRange:
1584  yuv.x = rgb.x * 0.257 + rgb.y * 0.516 + rgb.z * 0.100 + 0.063;
1585  yuv.y = rgb.x * -0.145 + rgb.y * -0.291 + rgb.z * 0.439 + 0.5;
1586  yuv.z = rgb.x * 0.429 + rgb.y * -0.368 + rgb.z * -0.071 + 0.5;
1587  break;
1588  }
1589  return yuv;
1590 }

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

Referenced by CreateTestYUVTextures().

◆ swap_nan() [1/2]

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

Definition at line 1350 of file rect_unittests.cc.

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

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

◆ swap_nan() [2/2]

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

Definition at line 1340 of file rect_unittests.cc.

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

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

Referenced by TEST().

◆ TEST() [1/465]

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

Definition at line 77 of file allocation_size_unittests.cc.

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

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

◆ TEST() [2/465]

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

Definition at line 110 of file allocation_size_unittests.cc.

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

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

◆ TEST() [3/465]

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

Definition at line 44 of file allocation_size_unittests.cc.

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

◆ TEST() [4/465]

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

Definition at line 10 of file allocation_size_unittests.cc.

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

◆ TEST() [5/465]

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

Definition at line 33 of file allocation_size_unittests.cc.

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

◆ TEST() [6/465]

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

Definition at line 55 of file allocation_size_unittests.cc.

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

◆ TEST() [7/465]

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

Definition at line 91 of file allocation_size_unittests.cc.

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

References impeller::saturated::b.

◆ TEST() [8/465]

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

Definition at line 49 of file allocation_size_unittests.cc.

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

◆ TEST() [9/465]

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

Definition at line 60 of file allocation_size_unittests.cc.

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

References impeller::saturated::b.

◆ TEST() [10/465]

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

Definition at line 82 of file allocator_unittests.cc.

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

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

◆ TEST() [11/465]

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

Definition at line 16 of file allocator_unittests.cc.

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

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

◆ TEST() [12/465]

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

Definition at line 38 of file allocator_vk_unittests.cc.

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

References impeller::AllocatorVK::FindMemoryTypeIndex().

◆ TEST() [13/465]

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

Definition at line 53 of file allocator_vk_unittests.cc.

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

References impeller::AllocatorVK::FindMemoryTypeIndex().

◆ TEST() [14/465]

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

Definition at line 19 of file allocator_vk_unittests.cc.

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

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

◆ TEST() [15/465]

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

Definition at line 264 of file base_unittests.cc.

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

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

◆ TEST() [16/465]

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

Definition at line 255 of file base_unittests.cc.

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

◆ TEST() [17/465]

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

Definition at line 248 of file base_unittests.cc.

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

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

◆ TEST() [18/465]

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

Definition at line 17 of file buffer_bindings_gles_unittests.cc.

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

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

◆ TEST() [19/465]

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

Definition at line 11 of file buffer_view_unittests.cc.

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

References buffer_view.

◆ TEST() [20/465]

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

Definition at line 16 of file buffer_view_unittests.cc.

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

References buffer_view.

◆ TEST() [21/465]

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

Definition at line 32 of file capabilities_unittests.cc.

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

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

◆ TEST() [22/465]

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

Definition at line 50 of file capabilities_unittests.cc.

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

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

◆ TEST() [23/465]

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

Definition at line 60 of file capabilities_unittests.cc.

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

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

◆ TEST() [24/465]

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

Definition at line 41 of file capabilities_unittests.cc.

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

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

◆ TEST() [25/465]

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

Definition at line 69 of file capabilities_unittests.cc.

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

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

◆ TEST() [26/465]

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

Definition at line 215 of file context_vk_unittests.cc.

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

◆ TEST() [27/465]

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

Definition at line 184 of file context_vk_unittests.cc.

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

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

◆ TEST() [28/465]

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

Definition at line 37 of file command_encoder_vk_unittests.cc.

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

References impeller::CommandBuffer::kCompleted.

◆ TEST() [29/465]

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

Definition at line 15 of file command_encoder_vk_unittests.cc.

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

◆ TEST() [30/465]

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

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

Definition at line 165 of file command_pool_vk_unittests.cc.

165  {
166  auto const context = MockVulkanContextBuilder().Build();
167 
168  {
169  // Fetch a pool (which will be created).
170  auto const recycler = context->GetCommandPoolRecycler();
171  auto pool = recycler->Get();
172 
173  // Allocate a large number of command buffers
174  for (auto i = 0; i < 64; i++) {
175  auto buffer = pool->CreateCommandBuffer();
176  pool->CollectCommandBuffer(std::move(buffer));
177  }
178 
179  // This normally is called at the end of a frame.
180  recycler->Dispose();
181  }
182 
183  // Wait for the pool to be reclaimed.
184  for (auto i = 0u; i < 2u; i++) {
185  auto waiter = fml::AutoResetWaitableEvent();
186  auto rattle = DeathRattle([&waiter]() { waiter.Signal(); });
187  {
188  UniqueResourceVKT<DeathRattle> resource(context->GetResourceManager(),
189  std::move(rattle));
190  }
191  waiter.Wait();
192  }
193 
194  // Command pool is reset but does not release resources.
195  auto called = GetMockVulkanFunctions(context->GetDevice());
196  EXPECT_EQ(std::count(called->begin(), called->end(), "vkResetCommandPool"),
197  1u);
198 
199  // Create the pool a second time, but dont use any command buffers.
200  {
201  // Fetch a pool (which will be created).
202  auto const recycler = context->GetCommandPoolRecycler();
203  auto pool = recycler->Get();
204 
205  // This normally is called at the end of a frame.
206  recycler->Dispose();
207  }
208 
209  // Wait for the pool to be reclaimed.
210  for (auto i = 0u; i < 2u; i++) {
211  auto waiter = fml::AutoResetWaitableEvent();
212  auto rattle = DeathRattle([&waiter]() { waiter.Signal(); });
213  {
214  UniqueResourceVKT<DeathRattle> resource(context->GetResourceManager(),
215  std::move(rattle));
216  }
217  waiter.Wait();
218  }
219 
220  // Verify that the cmd pool was trimmed.
221 
222  // Now check that we only ever created one pool and one command buffer.
223  called = GetMockVulkanFunctions(context->GetDevice());
224  EXPECT_EQ(std::count(called->begin(), called->end(),
225  "vkResetCommandPoolReleaseResources"),
226  1u);
227 
228  context->Shutdown();
229 }

◆ TEST() [32/465]

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

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

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

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

Definition at line 203 of file base_unittests.cc.

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

References impeller::ConditionVariable::Wait().

◆ TEST() [36/465]

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

Definition at line 158 of file base_unittests.cc.

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

References impeller::ConditionVariable::WaitFor().

◆ TEST() [37/465]

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

Definition at line 120 of file base_unittests.cc.

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

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

◆ TEST() [38/465]

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

Definition at line 141 of file base_unittests.cc.

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

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

◆ TEST() [39/465]

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

Definition at line 97 of file base_unittests.cc.

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

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

◆ TEST() [40/465]

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

Definition at line 306 of file context_vk_unittests.cc.

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

◆ TEST() [41/465]

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

Definition at line 335 of file context_vk_unittests.cc.

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

◆ TEST() [42/465]

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

Definition at line 152 of file context_vk_unittests.cc.

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

References impeller::CapabilitiesVK::AreValidationsEnabled().

◆ TEST() [43/465]

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

Definition at line 166 of file context_vk_unittests.cc.

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

References impeller::CapabilitiesVK::AreValidationsEnabled().

◆ TEST() [44/465]

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

Definition at line 17 of file context_vk_unittests.cc.

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

References impeller::ContextVK::ChooseThreadCountForWorkers().

◆ TEST() [45/465]

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

Definition at line 95 of file context_vk_unittests.cc.

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

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

◆ TEST() [46/465]

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

Definition at line 136 of file context_vk_unittests.cc.

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

References impeller::PipelineDescriptor::SetVertexDescriptor().

◆ TEST() [47/465]

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

Definition at line 30 of file context_vk_unittests.cc.

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

◆ TEST() [48/465]

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

Definition at line 45 of file context_vk_unittests.cc.

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

◆ TEST() [49/465]

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

Definition at line 114 of file context_vk_unittests.cc.

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

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

◆ TEST() [50/465]

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

Definition at line 283 of file context_vk_unittests.cc.

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

References data.

◆ TEST() [51/465]

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

Definition at line 264 of file context_vk_unittests.cc.

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

References data.

◆ TEST() [52/465]

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

Definition at line 245 of file context_vk_unittests.cc.

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

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

◆ TEST() [53/465]

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

Definition at line 256 of file context_vk_unittests.cc.

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

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

◆ TEST() [54/465]

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

Definition at line 76 of file context_vk_unittests.cc.

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

◆ TEST() [55/465]

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

Definition at line 234 of file context_vk_unittests.cc.

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

References impeller::kR8G8B8A8UNormInt.

◆ TEST() [56/465]

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

Definition at line 16 of file descriptor_pool_vk_unittests.cc.

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

◆ TEST() [57/465]

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

Definition at line 127 of file descriptor_pool_vk_unittests.cc.

127  {
128  auto const context = MockVulkanContextBuilder().Build();
129 
130  auto cmd_buffer_1 = context->CreateCommandBuffer();
131  auto cmd_buffer_2 = context->CreateCommandBuffer();
132 
133  CommandBufferVK& vk_1 = CommandBufferVK::Cast(*cmd_buffer_1);
134  CommandBufferVK& vk_2 = CommandBufferVK::Cast(*cmd_buffer_2);
135 
136  EXPECT_EQ(&vk_1.GetDescriptorPool(), &vk_2.GetDescriptorPool());
137 
138  // Resetting resources creates a new pool.
139  context->DisposeThreadLocalCachedResources();
140 
141  auto cmd_buffer_3 = context->CreateCommandBuffer();
142  CommandBufferVK& vk_3 = CommandBufferVK::Cast(*cmd_buffer_3);
143 
144  EXPECT_NE(&vk_1.GetDescriptorPool(), &vk_3.GetDescriptorPool());
145 
146  context->Shutdown();
147 }

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

◆ TEST() [58/465]

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

Definition at line 66 of file descriptor_pool_vk_unittests.cc.

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

◆ TEST() [59/465]

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

Definition at line 28 of file descriptor_pool_vk_unittests.cc.

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

◆ TEST() [60/465]

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

Definition at line 25 of file device_buffer_gles_unittests.cc.

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

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

◆ TEST() [61/465]

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

Definition at line 89 of file draw_order_resolver_unittests.cc.

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

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

◆ TEST() [62/465]

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

Definition at line 33 of file draw_order_resolver_unittests.cc.

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

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

◆ TEST() [63/465]

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

Definition at line 114 of file draw_order_resolver_unittests.cc.

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

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

◆ TEST() [64/465]

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

Definition at line 12 of file draw_order_resolver_unittests.cc.

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

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

◆ TEST() [65/465]

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

Definition at line 253 of file driver_info_vk_unittests.cc.

253  {
254  auto const context =
255  MockVulkanContextBuilder()
256  .SetPhysicalPropertiesCallback(
257  [](VkPhysicalDevice device, VkPhysicalDeviceProperties* prop) {
258  prop->vendorID = 0x1010;
259  prop->deviceType = VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU;
260  })
261  .Build();
262 
263  EXPECT_TRUE(context->GetDriverInfo()->IsKnownBadDriver());
264 }

◆ TEST() [66/465]

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

Definition at line 89 of file driver_info_vk_unittests.cc.

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

References CanBatchSubmitTest().

◆ TEST() [67/465]

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

Definition at line 145 of file driver_info_vk_unittests.cc.

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

References CanUseMipgeneration().

◆ TEST() [68/465]

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

Definition at line 39 of file driver_info_vk_unittests.cc.

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

◆ TEST() [69/465]

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

Definition at line 215 of file driver_info_vk_unittests.cc.

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

References CanUseFramebufferFetch().

◆ TEST() [70/465]

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

Definition at line 117 of file driver_info_vk_unittests.cc.

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

References CanUsePrimitiveRestartSubmitTest().

◆ TEST() [71/465]

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

Definition at line 165 of file driver_info_vk_unittests.cc.

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

References IsBadVersionTest().

◆ TEST() [72/465]

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

Definition at line 225 of file driver_info_vk_unittests.cc.

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

◆ TEST() [73/465]

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

Definition at line 160 of file driver_info_vk_unittests.cc.

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

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

◆ TEST() [74/465]

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

Definition at line 154 of file driver_info_vk_unittests.cc.

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

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

◆ TEST() [75/465]

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

Definition at line 185 of file driver_info_vk_unittests.cc.

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

References IsBadVersionTest().

◆ TEST() [76/465]

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

Definition at line 180 of file driver_info_vk_unittests.cc.

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

References IsBadVersionTest().

◆ TEST() [77/465]

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

Definition at line 139 of file geometry_unittests.cc.

139  {
140  auto matrix = Matrix::MakeScale(Vector2{3.0, 3.0});
141  EXPECT_EQ(Geometry::MakeStrokePath({}, 0.5)->ComputeAlphaCoverage(matrix), 1);
142  EXPECT_NEAR(Geometry::MakeStrokePath({}, 0.1)->ComputeAlphaCoverage(matrix),
143  0.6, 0.05);
144  EXPECT_NEAR(Geometry::MakeStrokePath({}, 0.05)->ComputeAlphaCoverage(matrix),
145  0.3, 0.05);
146  EXPECT_NEAR(Geometry::MakeStrokePath({}, 0.01)->ComputeAlphaCoverage(matrix),
147  0.1, 0.1);
148  EXPECT_NEAR(
149  Geometry::MakeStrokePath({}, 0.0000005)->ComputeAlphaCoverage(matrix),
150  1e-05, 0.001);
151  EXPECT_EQ(Geometry::MakeStrokePath({}, 0)->ComputeAlphaCoverage(matrix), 1);
152  EXPECT_EQ(Geometry::MakeStrokePath({}, 40)->ComputeAlphaCoverage(matrix), 1);
153 }
Point Vector2
Definition: point.h:331

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

◆ TEST() [78/465]

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 }
TRect< Scalar > Rect
Definition: rect.h:792

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

◆ TEST() [79/465]

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

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

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

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

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 }
TSize< Scalar > Size
Definition: size.h:171

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

◆ TEST() [84/465]

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

Definition at line 58 of file clip_stack_unittests.cc.

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

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

◆ TEST() [85/465]

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

Definition at line 88 of file clip_stack_unittests.cc.

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

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

◆ TEST() [86/465]

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

Definition at line 171 of file clip_stack_unittests.cc.

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

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

◆ TEST() [87/465]

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

Definition at line 193 of file clip_stack_unittests.cc.

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

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

◆ TEST() [88/465]

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

Definition at line 120 of file clip_stack_unittests.cc.

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

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

◆ TEST() [89/465]

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

Definition at line 146 of file clip_stack_unittests.cc.

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

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

◆ TEST() [90/465]

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

Definition at line 48 of file clip_stack_unittests.cc.

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

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

◆ TEST() [91/465]

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

Definition at line 14 of file clip_stack_unittests.cc.

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

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

◆ TEST() [92/465]

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

Definition at line 232 of file clip_stack_unittests.cc.

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

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

◆ TEST() [93/465]

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

Definition at line 281 of file clip_stack_unittests.cc.

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

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

◆ TEST() [94/465]

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

Definition at line 213 of file clip_stack_unittests.cc.

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

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

◆ TEST() [95/465]

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

Definition at line 86 of file fence_waiter_vk_unittests.cc.

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

References value.

◆ TEST() [96/465]

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

Definition at line 28 of file fence_waiter_vk_unittests.cc.

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

References value.

◆ TEST() [97/465]

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

Definition at line 40 of file fence_waiter_vk_unittests.cc.

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

References value.

◆ TEST() [98/465]

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

Definition at line 57 of file fence_waiter_vk_unittests.cc.

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

References value.

◆ TEST() [99/465]

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

Definition at line 19 of file fence_waiter_vk_unittests.cc.

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

References value.

◆ TEST() [100/465]

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

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 }

References value.

◆ TEST() [102/465]

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

Definition at line 15 of file filter_input_unittests.cc.

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

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

◆ TEST() [103/465]

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

Definition at line 11 of file formats_vk_unittests.cc.

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

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

◆ TEST() [104/465]

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

Definition at line 458 of file gaussian_blur_filter_contents_unittests.cc.

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

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

◆ TEST() [105/465]

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

Definition at line 225 of file gaussian_blur_filter_contents_unittests.cc.

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

References impeller::GaussianBlurFilterContents::CalculateScale().

◆ TEST() [106/465]

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

Definition at line 621 of file gaussian_blur_filter_contents_unittests.cc.

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

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

◆ TEST() [107/465]

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

Definition at line 468 of file gaussian_blur_filter_contents_unittests.cc.

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

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

◆ TEST() [108/465]

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

Definition at line 121 of file gaussian_blur_filter_contents_unittests.cc.

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

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

◆ TEST() [109/465]

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

Definition at line 132 of file gaussian_blur_filter_contents_unittests.cc.

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

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

◆ TEST() [110/465]

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

Definition at line 145 of file gaussian_blur_filter_contents_unittests.cc.

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

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

◆ TEST() [111/465]

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

Definition at line 113 of file gaussian_blur_filter_contents_unittests.cc.

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

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

◆ TEST() [112/465]

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

Definition at line 208 of file gaussian_blur_filter_contents_unittests.cc.

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

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

◆ TEST() [113/465]

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

Definition at line 567 of file gaussian_blur_filter_contents_unittests.cc.

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

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

◆ TEST() [114/465]

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

Definition at line 492 of file gaussian_blur_filter_contents_unittests.cc.

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

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

◆ TEST() [115/465]

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

Definition at line 1709 of file geometry_unittests.cc.

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

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

◆ TEST() [116/465]

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

Definition at line 1718 of file geometry_unittests.cc.

1718  {
1719  {
1720  auto deg = Degrees{90.0};
1721  Radians rad = deg;
1722  ASSERT_FLOAT_EQ(rad.radians, kPiOver2);
1723  }
1724 }
constexpr float kPiOver2
Definition: constants.h:32

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

◆ TEST() [117/465]

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

Definition at line 593 of file geometry_unittests.cc.

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

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

◆ TEST() [118/465]

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

Definition at line 580 of file geometry_unittests.cc.

580  {
581  ASSERT_EQ((Size{128, 128}.MipCount()), 6u);
582  ASSERT_EQ((Size{128, 256}.MipCount()), 7u);
583  ASSERT_EQ((Size{128, 130}.MipCount()), 7u);
584  ASSERT_EQ((Size{128, 257}.MipCount()), 8u);
585  ASSERT_EQ((Size{257, 128}.MipCount()), 8u);
586  ASSERT_EQ((Size{128, 0}.MipCount()), 1u);
587  ASSERT_EQ((Size{128, -25}.MipCount()), 1u);
588  ASSERT_EQ((Size{-128, 25}.MipCount()), 1u);
589  ASSERT_EQ((Size{1, 1}.MipCount()), 1u);
590  ASSERT_EQ((Size{0, 0}.MipCount()), 1u);
591 }
constexpr size_t MipCount() const
Definition: size.h:140

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

◆ TEST() [119/465]

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

Definition at line 616 of file geometry_unittests.cc.

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

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

◆ TEST() [120/465]

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

Definition at line 646 of file geometry_unittests.cc.

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

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

◆ TEST() [121/465]

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

Definition at line 1276 of file geometry_unittests.cc.

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

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

◆ TEST() [122/465]

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

Definition at line 1310 of file geometry_unittests.cc.

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

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

◆ TEST() [123/465]

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

Definition at line 798 of file geometry_unittests.cc.

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

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

◆ TEST() [124/465]

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

Definition at line 1226 of file geometry_unittests.cc.

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

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

◆ TEST() [125/465]

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

Definition at line 1483 of file geometry_unittests.cc.

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

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

◆ TEST() [126/465]

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

Definition at line 1692 of file geometry_unittests.cc.

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

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

◆ TEST() [127/465]

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

Definition at line 1443 of file geometry_unittests.cc.

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

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

◆ TEST() [128/465]

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

Definition at line 1421 of file geometry_unittests.cc.

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

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

◆ TEST() [129/465]

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

Definition at line 1509 of file geometry_unittests.cc.

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

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

◆ TEST() [130/465]

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

Definition at line 1463 of file geometry_unittests.cc.

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

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

◆ TEST() [131/465]

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

Definition at line 1378 of file geometry_unittests.cc.

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

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

◆ TEST() [132/465]

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

Definition at line 1801 of file geometry_unittests.cc.

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

◆ TEST() [133/465]

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

Definition at line 1401 of file geometry_unittests.cc.

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

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

◆ TEST() [134/465]

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

Definition at line 1529 of file geometry_unittests.cc.

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

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

◆ TEST() [135/465]

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

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

Definition at line 1823 of file geometry_unittests.cc.

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

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

◆ TEST() [137/465]

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

Definition at line 1893 of file geometry_unittests.cc.

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

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

◆ TEST() [138/465]

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

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

Definition at line 79 of file geometry_unittests.cc.

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

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

◆ TEST() [140/465]

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

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

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

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

Definition at line 408 of file geometry_unittests.cc.

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

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

◆ TEST() [144/465]

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

Definition at line 432 of file geometry_unittests.cc.

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

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

◆ TEST() [145/465]

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

Definition at line 333 of file geometry_unittests.cc.

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

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

◆ TEST() [146/465]

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

Definition at line 481 of file geometry_unittests.cc.

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

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

◆ TEST() [147/465]

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

Definition at line 360 of file geometry_unittests.cc.

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

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

◆ TEST() [148/465]

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

Definition at line 384 of file geometry_unittests.cc.

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

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

◆ TEST() [149/465]

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

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

Definition at line 1726 of file geometry_unittests.cc.

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

References impeller::Matrix::MakeTranslation().

◆ TEST() [151/465]

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

Definition at line 298 of file geometry_unittests.cc.

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

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

◆ TEST() [152/465]

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

Definition at line 455 of file geometry_unittests.cc.

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

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

◆ TEST() [153/465]

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

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

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

Definition at line 938 of file geometry_unittests.cc.

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

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

◆ TEST() [156/465]

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

Definition at line 975 of file geometry_unittests.cc.

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

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

◆ TEST() [157/465]

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

Definition at line 1113 of file geometry_unittests.cc.

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

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

◆ TEST() [158/465]

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

Definition at line 893 of file geometry_unittests.cc.

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

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

◆ TEST() [159/465]

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

Definition at line 873 of file geometry_unittests.cc.

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

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

◆ TEST() [160/465]

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

Definition at line 1092 of file geometry_unittests.cc.

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

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

◆ TEST() [161/465]

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

Definition at line 678 of file geometry_unittests.cc.

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

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

◆ TEST() [162/465]

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

Definition at line 1155 of file geometry_unittests.cc.

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

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

◆ TEST() [163/465]

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

Definition at line 1071 of file geometry_unittests.cc.

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

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

◆ TEST() [164/465]

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

Definition at line 1004 of file geometry_unittests.cc.

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

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

◆ TEST() [165/465]

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

Definition at line 1753 of file geometry_unittests.cc.

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

◆ TEST() [166/465]

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

Definition at line 913 of file geometry_unittests.cc.

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

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

◆ TEST() [167/465]

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

Definition at line 945 of file geometry_unittests.cc.

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

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

◆ TEST() [168/465]

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

Definition at line 1134 of file geometry_unittests.cc.

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

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

◆ TEST() [169/465]

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

Definition at line 527 of file geometry_unittests.cc.

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

References ASSERT_QUATERNION_NEAR, and impeller::kPiOver4.

◆ TEST() [170/465]

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

Definition at line 538 of file geometry_unittests.cc.

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

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

◆ TEST() [171/465]

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

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

Definition at line 31 of file geometry_unittests.cc.

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

References impeller::ScalarNearlyEqual().

◆ TEST() [173/465]

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

Definition at line 1210 of file geometry_unittests.cc.

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

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

◆ TEST() [174/465]

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

Definition at line 1187 of file geometry_unittests.cc.

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

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

◆ TEST() [175/465]

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

Definition at line 1182 of file geometry_unittests.cc.

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

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

◆ TEST() [176/465]

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

Definition at line 1176 of file geometry_unittests.cc.

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

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

◆ TEST() [177/465]

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

Definition at line 738 of file geometry_unittests.cc.

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

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

◆ TEST() [178/465]

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

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

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

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

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

Definition at line 1817 of file geometry_unittests.cc.

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

References impeller::Color::ToIColor().

◆ TEST() [183/465]

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

Definition at line 1120 of file geometry_unittests.cc.

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

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

◆ TEST() [184/465]

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

Definition at line 1099 of file geometry_unittests.cc.

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

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

◆ TEST() [185/465]

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

Definition at line 1162 of file geometry_unittests.cc.

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

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

◆ TEST() [186/465]

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

Definition at line 1078 of file geometry_unittests.cc.

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

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

◆ TEST() [187/465]

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

Definition at line 1057 of file geometry_unittests.cc.

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

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

◆ TEST() [188/465]

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

Definition at line 1769 of file geometry_unittests.cc.

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

◆ TEST() [189/465]

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

Definition at line 1141 of file geometry_unittests.cc.

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

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

◆ TEST() [190/465]

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

Definition at line 1127 of file geometry_unittests.cc.

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

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

◆ TEST() [191/465]

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

Definition at line 1106 of file geometry_unittests.cc.

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

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

◆ TEST() [192/465]

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

Definition at line 1011 of file geometry_unittests.cc.

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

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

◆ TEST() [193/465]

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

Definition at line 1169 of file geometry_unittests.cc.

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

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

◆ TEST() [194/465]

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

Definition at line 1085 of file geometry_unittests.cc.

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

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

◆ TEST() [195/465]

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

Definition at line 1064 of file geometry_unittests.cc.

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

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

◆ TEST() [196/465]

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

Definition at line 1785 of file geometry_unittests.cc.

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

◆ TEST() [197/465]

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

Definition at line 1148 of file geometry_unittests.cc.

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

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

◆ TEST() [198/465]

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

Definition at line 65 of file matrix_filter_contents_unittests.cc.

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

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

◆ TEST() [199/465]

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

Definition at line 77 of file matrix_filter_contents_unittests.cc.

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

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

◆ TEST() [200/465]

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

Definition at line 45 of file matrix_filter_contents_unittests.cc.

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

References impeller::MatrixFilterContents::GetFilterCoverage().

◆ TEST() [201/465]

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

Definition at line 54 of file matrix_filter_contents_unittests.cc.

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

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

◆ TEST() [202/465]

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

Definition at line 28 of file matrix_unittests.cc.

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

References x.

◆ TEST() [203/465]

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

Definition at line 263 of file matrix_unittests.cc.

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

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

◆ TEST() [204/465]

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

Definition at line 274 of file matrix_unittests.cc.

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

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

◆ TEST() [205/465]

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

Definition at line 282 of file matrix_unittests.cc.

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

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

◆ TEST() [206/465]

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

Definition at line 58 of file matrix_unittests.cc.

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

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

◆ TEST() [207/465]

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

Definition at line 40 of file matrix_unittests.cc.

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

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

◆ TEST() [208/465]

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

Definition at line 76 of file matrix_unittests.cc.

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

References impeller::Matrix::MakeTranslation().

◆ TEST() [209/465]

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

Definition at line 203 of file matrix_unittests.cc.

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

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

◆ TEST() [210/465]

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

Definition at line 170 of file matrix_unittests.cc.

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

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

◆ TEST() [211/465]

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

Definition at line 132 of file matrix_unittests.cc.

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

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

◆ TEST() [212/465]

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

Definition at line 105 of file matrix_unittests.cc.

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

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

◆ TEST() [213/465]

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

Definition at line 83 of file matrix_unittests.cc.

83  {
84  EXPECT_TRUE(Matrix::MakeTranslation({100, 100, 0}).IsTranslationOnly());
85  EXPECT_TRUE(Matrix::MakeTranslation({100, 100, 0}).IsTranslationScaleOnly());
86  EXPECT_TRUE(Matrix::MakeTranslation({0, 100, 0}).IsTranslationOnly());
87  EXPECT_TRUE(Matrix::MakeTranslation({0, 100, 0}).IsTranslationScaleOnly());
88  EXPECT_TRUE(Matrix::MakeTranslation({100, 0, 0}).IsTranslationOnly());
89  EXPECT_TRUE(Matrix::MakeTranslation({100, 0, 0}).IsTranslationScaleOnly());
90  EXPECT_TRUE(Matrix().IsTranslationOnly());
91  EXPECT_TRUE(Matrix().IsTranslationScaleOnly());
92 }

References impeller::Matrix::MakeTranslation().

◆ TEST() [214/465]

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

Definition at line 94 of file matrix_unittests.cc.

94  {
95  EXPECT_FALSE(Matrix::MakeScale({100, 100, 1}).IsTranslationOnly());
96  EXPECT_TRUE(Matrix::MakeScale({100, 100, 1}).IsTranslationScaleOnly());
97  EXPECT_FALSE(Matrix::MakeScale({1, 100, 1}).IsTranslationOnly());
98  EXPECT_TRUE(Matrix::MakeScale({1, 100, 1}).IsTranslationScaleOnly());
99  EXPECT_FALSE(Matrix::MakeScale({100, 1, 1}).IsTranslationOnly());
100  EXPECT_TRUE(Matrix::MakeScale({100, 1, 1}).IsTranslationScaleOnly());
101  EXPECT_TRUE(Matrix().IsTranslationOnly());
102  EXPECT_TRUE(Matrix().IsTranslationScaleOnly());
103 }

References impeller::Matrix::MakeScale().

◆ TEST() [215/465]

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

Definition at line 301 of file matrix_unittests.cc.

301  {
302  EXPECT_TRUE(MatrixNear(
303  Matrix::MakeTranslateScale({1, 1, 1.0 / 1024}, {10, 10, 1.0 / 1024}),
304  Matrix::MakeTranslation({10, 10, 1.0 / 1024}) *
305  Matrix::MakeScale({1, 1, 1.0 / 1024})));
306 
307  EXPECT_TRUE(MatrixNear(
308  Matrix::MakeTranslateScale({2, 2, 2}, {10, 10, 0}),
309  Matrix::MakeTranslation({10, 10, 0}) * Matrix::MakeScale({2, 2, 2})));
310 
311  EXPECT_TRUE(MatrixNear(
312  Matrix::MakeTranslateScale({0, 0, 0}, {0, 0, 0}),
313  Matrix::MakeTranslation({0, 0, 0}) * Matrix::MakeScale({0, 0, 0})));
314 }
inline ::testing::AssertionResult MatrixNear(impeller::Matrix a, impeller::Matrix b)

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

◆ TEST() [216/465]

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

Definition at line 15 of file matrix_unittests.cc.

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

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

◆ TEST() [217/465]

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

Definition at line 34 of file matrix_unittests.cc.

34  {
35  Matrix x;
36  Matrix y = x.Translate({1, 0, 0});
37  EXPECT_FALSE(x.Equals(y));
38 }

References x.

◆ TEST() [218/465]

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

Definition at line 250 of file matrix_unittests.cc.

250  {
251  Matrix matrix = Matrix::MakeColumn(
252  // clang-format off
253  2.0f, 3.0f, 5.0f, 7.0f,
254  11.0f, 13.0f, 17.0f, 19.0f,
255  23.0f, 29.0f, 31.0f, 37.0f,
256  41.0f, 43.0f, 47.0f, 53.0f
257  // clang-format on
258  );
259  EXPECT_EQ(matrix.TransformHomogenous({1.0f, -1.0f}),
260  Vector3(32.0f, 33.0f, 41.0f));
261 }

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

◆ TEST() [219/465]

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

Definition at line 289 of file matrix_unittests.cc.

289  {
290  Matrix m = Matrix::MakeRow(1.0, 0.0, 0.0, 10.0, //
291  0.0, 1.0, 0.0, 20.0, //
292  0.0, 0.0, 1.0, 0.0, //
293  0.0, 2.0, 0.0, 30.0);
294  Matrix result = m.Translate({100, 200});
295  EXPECT_TRUE(MatrixNear(result, Matrix::MakeRow(1.0, 0.0, 0.0, 110.0, //
296  0.0, 1.0, 0.0, 220.0, //
297  0.0, 0.0, 1.0, 0.0, //
298  0.0, 2.0, 0.0, 430.0)));
299 }

References impeller::Matrix::MakeRow(), MatrixNear(), and impeller::Matrix::Translate().

◆ TEST() [220/465]

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

Definition at line 485 of file path_unittests.cc.

485  {
486  PathBuilder builder;
487  auto path =
488  builder.AddCubicCurve({120, 160}, {25, 200}, {220, 260}, {220, 40})
489  .TakePath();
490  auto box = path.GetBoundingBox();
491  Rect expected = Rect::MakeXYWH(93.9101, 40, 126.09, 158.862);
492  ASSERT_TRUE(box.has_value());
493  ASSERT_RECT_NEAR(box.value_or(Rect::MakeMaximum()), expected);
494 }
#define ASSERT_RECT_NEAR(a, b)

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

◆ TEST() [221/465]

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

Definition at line 496 of file path_unittests.cc.

496  {
497  PathBuilder builder;
498  builder.AddRoundRect(
499  RoundRect::MakeRectRadius(Rect::MakeXYWH(10, 10, 300, 300), 50));
500  auto path = builder.TakePath();
501  auto actual = path.GetBoundingBox();
502  Rect expected = Rect::MakeXYWH(10, 10, 300, 300);
503 
504  ASSERT_TRUE(actual.has_value());
505  ASSERT_RECT_NEAR(actual.value_or(Rect::MakeMaximum()), expected);
506 }

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

◆ TEST() [222/465]

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

Definition at line 666 of file path_unittests.cc.

666  {
667  PathBuilder builder;
668  builder.MoveTo({10, 10});
669  builder.LineTo({20, 20});
670  builder.SetBounds(Rect::MakeLTRB(0, 0, 100, 100));
671  builder.SetConvexity(Convexity::kConvex);
672 
673  auto path_a = builder.TakePath(FillType::kOdd);
674  // NOLINTNEXTLINE(performance-unnecessary-copy-initialization)
675  auto path_b = path_a;
676 
677  EXPECT_EQ(path_a.GetBoundingBox(), path_b.GetBoundingBox());
678  EXPECT_EQ(path_a.GetFillType(), path_b.GetFillType());
679  EXPECT_EQ(path_a.IsConvex(), path_b.IsConvex());
680 
681  auto poly_a = path_a.CreatePolyline(1.0);
682  auto poly_b = path_b.CreatePolyline(1.0);
683 
684  ASSERT_EQ(poly_a.points->size(), poly_b.points->size());
685  ASSERT_EQ(poly_a.contours.size(), poly_b.contours.size());
686 
687  for (auto i = 0u; i < poly_a.points->size(); i++) {
688  EXPECT_EQ((*poly_a.points)[i], (*poly_b.points)[i]);
689  }
690 
691  for (auto i = 0u; i < poly_a.contours.size(); i++) {
692  EXPECT_EQ(poly_a.contours[i].start_index, poly_b.contours[i].start_index);
693  EXPECT_EQ(poly_a.contours[i].start_direction,
694  poly_b.contours[i].start_direction);
695  }
696 }

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

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

Definition at line 636 of file path_unittests.cc.

636  {
637  PathBuilder builder;
638  auto path = builder.LineTo({0, 10})
639  .LineTo({10, 10})
640  .MoveTo({30, 30}) // Moves to (30, 30)
641  .Close() // No Op
642  .Close() // Still No op
643  .TakePath();
644 
645  EXPECT_EQ(path.GetComponentCount(), 4u);
646  EXPECT_EQ(path.GetComponentCount(Path::ComponentType::kLinear), 2u);
647  EXPECT_EQ(path.GetComponentCount(Path::ComponentType::kContour), 2u);
648 }
void MoveTo(PathBuilder *builder, Scalar x, Scalar y)
Definition: tessellator.cc:20
void LineTo(PathBuilder *builder, Scalar x, Scalar y)
Definition: tessellator.cc:24
void Close(PathBuilder *builder)
Definition: tessellator.cc:38

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

◆ TEST() [224/465]

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

Definition at line 650 of file path_unittests.cc.

650  {
651  PathBuilder builder;
652  // Create a path that has a current position at the origin when close is
653  // called. This should not insert a new line segment
654  auto path = builder.LineTo({10, 0})
655  .LineTo({10, 10})
656  .LineTo({0, 10})
657  .LineTo({0, 0})
658  .Close()
659  .TakePath();
660 
661  EXPECT_EQ(path.GetComponentCount(), 6u);
662  EXPECT_EQ(path.GetComponentCount(Path::ComponentType::kLinear), 4u);
663  EXPECT_EQ(path.GetComponentCount(Path::ComponentType::kContour), 2u);
664 }

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

◆ TEST() [225/465]

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

Definition at line 470 of file path_unittests.cc.

470  {
471  PathBuilder builder;
472  auto path =
473  builder.CubicCurveTo(Point(10, 10), Point(-10, -10), Point(20, 20))
474  .TakePath();
475 
476  CubicPathComponent cubic;
477  path.GetCubicComponentAtIndex(1, cubic);
478 
479  EXPECT_EQ(cubic.p1, Point(0, 0));
480  EXPECT_EQ(cubic.cp1, Point(10, 10));
481  EXPECT_EQ(cubic.cp2, Point(-10, -10));
482  EXPECT_EQ(cubic.p2, Point(20, 20));
483 }

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

◆ TEST() [226/465]

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

Definition at line 17 of file path_unittests.cc.

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

References polyline.

◆ TEST() [227/465]

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

Definition at line 531 of file path_unittests.cc.

531  {
532  auto path = PathBuilder{}.TakePath();
533  ASSERT_EQ(path.GetComponentCount(), 1u);
534 
535  ContourComponent c;
536  path.GetContourComponentAtIndex(0, c);
537  ASSERT_POINT_NEAR(c.destination, Point());
538 
539  Path::Polyline polyline = path.CreatePolyline(1.0f);
540  ASSERT_TRUE(polyline.points->empty());
541  ASSERT_TRUE(polyline.contours.empty());
542 }

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

◆ TEST() [228/465]

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

Definition at line 27 of file path_unittests.cc.

27  {
28  PathBuilder builder;
29  auto path = builder.TakePath();
30 
31  EXPECT_TRUE(path.IsEmpty());
32 }

References impeller::PathBuilder::TakePath().

◆ TEST() [229/465]

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

Definition at line 508 of file path_unittests.cc.

508  {
509  CubicPathComponent cubic{{11.769268, 252.883148},
510  {-6.2857933, 204.356461},
511  {-4.53997231, 156.552902},
512  {17.0067291, 109.472488}};
513  auto points = cubic.Extrema();
514 
515  ASSERT_EQ(points.size(), static_cast<size_t>(3));
516  ASSERT_POINT_NEAR(points[2], cubic.Solve(0.455916));
517 }

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

◆ TEST() [230/465]

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

Definition at line 698 of file path_unittests.cc.

698  {
699  Path path = PathBuilder{}
700  .AddRoundRect(RoundRect::MakeRectRadius(
701  Rect::MakeLTRB(0, 0, 100, 100), 10))
702  .TakePath();
703  auto [points, contours] = path.CountStorage(1.0);
704 
705  std::vector<Point> point_storage(points);
706  std::vector<uint16_t> index_storage(points + (contours - 1));
707 
708  FanVertexWriter writer(point_storage.data(), index_storage.data());
709  path.WritePolyline(1.0, writer);
710 
711  EXPECT_LE(writer.GetIndexCount(), index_storage.size());
712  EXPECT_EQ(point_storage[0], Point(10, 0));
713 }

References impeller::PathBuilder::AddRoundRect(), impeller::Path::CountStorage(), impeller::FanVertexWriter::GetIndexCount(), impeller::TRect< Scalar >::MakeLTRB(), impeller::RoundRect::MakeRectRadius(), impeller::PathBuilder::TakePath(), and impeller::Path::WritePolyline().

◆ TEST() [231/465]

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

Definition at line 765 of file path_unittests.cc.

765  {
766  PathBuilder builder{};
767  for (auto i = 0; i < 10; i++) {
768  builder.AddRoundRect(
769  RoundRect::MakeRectRadius(Rect::MakeLTRB(0 + i, 0 + i, 100, 100), 10));
770  }
771  auto path = builder.TakePath();
772  auto [points, contours] = path.CountStorage(1.0);
773 
774  std::vector<Point> point_storage(points);
775  std::vector<uint16_t> index_storage(points + (contours - 1));
776 
777  FanVertexWriter writer(point_storage.data(), index_storage.data());
778  path.WritePolyline(1.0, writer);
779 
780  EXPECT_LE(writer.GetIndexCount(), index_storage.size());
781  EXPECT_EQ(point_storage[0], Point(10, 0));
782 }

References impeller::PathBuilder::AddRoundRect(), impeller::Path::CountStorage(), impeller::FanVertexWriter::GetIndexCount(), impeller::TRect< Scalar >::MakeLTRB(), impeller::RoundRect::MakeRectRadius(), and impeller::PathBuilder::TakePath().

◆ TEST() [232/465]

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

Definition at line 716 of file path_unittests.cc.

716  {
717  // Create a rectangle that lacks an explicit close.
718  Path path = PathBuilder{}
719  .LineTo({100, 0})
720  .LineTo({100, 100})
721  .LineTo({0, 100})
722  .TakePath();
723 
724  std::vector<Point> expected = {{0, 0}, {100, 0}, {100, 100},
725  {0, 100}, {0, 0}, {0, 0}};
726  std::vector<uint16_t> expected_indices = {0, 1, 2, 3, 0xFFFF, 0};
727 
728  auto [points, contours] = path.CountStorage(1.0);
729 
730  std::vector<Point> point_storage(points);
731  std::vector<uint16_t> index_storage(points + (contours - 1));
732 
733  FanVertexWriter writer(point_storage.data(), index_storage.data());
734  path.WritePolyline(1.0, writer);
735 
736  EXPECT_LE(index_storage, expected_indices);
737  EXPECT_EQ(point_storage, expected);
738 }

References impeller::Path::CountStorage(), impeller::LineTo(), impeller::PathBuilder::LineTo(), and impeller::Path::WritePolyline().

◆ TEST() [233/465]

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

Definition at line 306 of file path_unittests.cc.

306  {
307  Path::Polyline polyline = PathBuilder{}
308  .AddRect(Rect::MakeLTRB(50, 60, 70, 80))
309  .TakePath()
310  .CreatePolyline(1.0f);
311  ASSERT_EQ(polyline.contours.size(), 1u);
312  ASSERT_TRUE(polyline.contours[0].is_closed);
313  ASSERT_EQ(polyline.contours[0].start_index, 0u);
314  ASSERT_EQ(polyline.points->size(), 5u);
315  ASSERT_EQ(polyline.GetPoint(0), Point(50, 60));
316  ASSERT_EQ(polyline.GetPoint(1), Point(70, 60));
317  ASSERT_EQ(polyline.GetPoint(2), Point(70, 80));
318  ASSERT_EQ(polyline.GetPoint(3), Point(50, 80));
319  ASSERT_EQ(polyline.GetPoint(4), Point(50, 60));
320 }

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

◆ TEST() [234/465]

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

Definition at line 820 of file path_unittests.cc.

820  {
821  auto test_isolation =
822  [](const std::function<void(PathBuilder & builder)>& mutator,
823  bool will_close, Point mutation_offset, const std::string& label) {
824  PathBuilder builder;
825  builder.MoveTo({10, 10});
826  builder.LineTo({20, 20});
827  builder.LineTo({20, 10});
828 
829  auto verify_path = [](const Path& path, bool is_mutated, bool is_closed,
830  Point offset, const std::string& label) {
831  if (is_mutated) {
832  // We can only test the initial state before the mutator did
833  // its work. We have >= 3 components and the first 3 components
834  // will match what we saw before the mutation.
835  EXPECT_GE(path.GetComponentCount(), 3u) << label;
836  } else {
837  EXPECT_EQ(path.GetComponentCount(), 3u) << label;
838  }
839  {
840  ContourComponent contour;
841  EXPECT_TRUE(path.GetContourComponentAtIndex(0, contour)) << label;
842  EXPECT_EQ(contour.destination, offset + Point(10, 10)) << label;
843  EXPECT_EQ(contour.IsClosed(), is_closed) << label;
844  }
845  {
846  LinearPathComponent line;
847  EXPECT_TRUE(path.GetLinearComponentAtIndex(1, line)) << label;
848  EXPECT_EQ(line.p1, offset + Point(10, 10)) << label;
849  EXPECT_EQ(line.p2, offset + Point(20, 20)) << label;
850  }
851  {
852  LinearPathComponent line;
853  EXPECT_TRUE(path.GetLinearComponentAtIndex(2, line)) << label;
854  EXPECT_EQ(line.p1, offset + Point(20, 20)) << label;
855  EXPECT_EQ(line.p2, offset + Point(20, 10)) << label;
856  }
857  };
858 
859  auto path1 = builder.CopyPath();
860  verify_path(path1, false, false, {},
861  "Initial Path1 state before " + label);
862 
863  for (int i = 0; i < 10; i++) {
864  auto path = builder.CopyPath();
865  verify_path(
866  path, false, false, {},
867  "Extra CopyPath #" + std::to_string(i + 1) + " for " + label);
868  }
869  mutator(builder);
870  verify_path(path1, false, false, {},
871  "Path1 state after subsequent " + label);
872 
873  auto path2 = builder.CopyPath();
874  verify_path(path1, false, false, {},
875  "Path1 state after subsequent " + label + " and CopyPath");
876  verify_path(path2, true, will_close, mutation_offset,
877  "Initial Path2 state with subsequent " + label);
878  };
879 
880  test_isolation(
881  [](PathBuilder& builder) { //
882  builder.SetConvexity(Convexity::kConvex);
883  },
884  false, {}, "SetConvex");
885 
886  test_isolation(
887  [](PathBuilder& builder) { //
888  builder.SetConvexity(Convexity::kUnknown);
889  },
890  false, {}, "SetUnknownConvex");
891 
892  test_isolation(
893  [](PathBuilder& builder) { //
894  builder.Close();
895  },
896  true, {}, "Close");
897 
898  test_isolation(
899  [](PathBuilder& builder) {
900  builder.MoveTo({20, 30}, false);
901  },
902  false, {}, "Absolute MoveTo");
903 
904  test_isolation(
905  [](PathBuilder& builder) {
906  builder.MoveTo({20, 30}, true);
907  },
908  false, {}, "Relative MoveTo");
909 
910  test_isolation(
911  [](PathBuilder& builder) {
912  builder.LineTo({20, 30}, false);
913  },
914  false, {}, "Absolute LineTo");
915 
916  test_isolation(
917  [](PathBuilder& builder) {
918  builder.LineTo({20, 30}, true);
919  },
920  false, {}, "Relative LineTo");
921 
922  test_isolation(
923  [](PathBuilder& builder) { //
924  builder.HorizontalLineTo(100, false);
925  },
926  false, {}, "Absolute HorizontalLineTo");
927 
928  test_isolation(
929  [](PathBuilder& builder) { //
930  builder.HorizontalLineTo(100, true);
931  },
932  false, {}, "Relative HorizontalLineTo");
933 
934  test_isolation(
935  [](PathBuilder& builder) { //
936  builder.VerticalLineTo(100, false);
937  },
938  false, {}, "Absolute VerticalLineTo");
939 
940  test_isolation(
941  [](PathBuilder& builder) { //
942  builder.VerticalLineTo(100, true);
943  },
944  false, {}, "Relative VerticalLineTo");
945 
946  test_isolation(
947  [](PathBuilder& builder) {
948  builder.QuadraticCurveTo({20, 30}, {30, 20}, false);
949  },
950  false, {}, "Absolute QuadraticCurveTo");
951 
952  test_isolation(
953  [](PathBuilder& builder) {
954  builder.QuadraticCurveTo({20, 30}, {30, 20}, true);
955  },
956  false, {}, "Relative QuadraticCurveTo");
957 
958  test_isolation(
959  [](PathBuilder& builder) {
960  builder.CubicCurveTo({20, 30}, {30, 20}, {30, 30}, false);
961  },
962  false, {}, "Absolute CubicCurveTo");
963 
964  test_isolation(
965  [](PathBuilder& builder) {
966  builder.CubicCurveTo({20, 30}, {30, 20}, {30, 30}, true);
967  },
968  false, {}, "Relative CubicCurveTo");
969 
970  test_isolation(
971  [](PathBuilder& builder) {
972  builder.AddLine({100, 100}, {150, 100});
973  },
974  false, {}, "AddLine");
975 
976  test_isolation(
977  [](PathBuilder& builder) {
978  builder.AddRect(Rect::MakeLTRB(100, 100, 120, 120));
979  },
980  false, {}, "AddRect");
981 
982  test_isolation(
983  [](PathBuilder& builder) {
984  builder.AddOval(Rect::MakeLTRB(100, 100, 120, 120));
985  },
986  false, {}, "AddOval");
987 
988  test_isolation(
989  [](PathBuilder& builder) {
990  builder.AddCircle({100, 100}, 20);
991  },
992  false, {}, "AddCircle");
993 
994  test_isolation(
995  [](PathBuilder& builder) {
996  builder.AddArc(Rect::MakeLTRB(100, 100, 120, 120), Degrees(10),
997  Degrees(170));
998  },
999  false, {}, "AddArc");
1000 
1001  test_isolation(
1002  [](PathBuilder& builder) {
1003  builder.AddQuadraticCurve({100, 100}, {150, 100}, {150, 150});
1004  },
1005  false, {}, "AddQuadraticCurve");
1006 
1007  test_isolation(
1008  [](PathBuilder& builder) {
1009  builder.AddCubicCurve({100, 100}, {150, 100}, {100, 150}, {150, 150});
1010  },
1011  false, {}, "AddCubicCurve");
1012 
1013  test_isolation(
1014  [](PathBuilder& builder) {
1015  builder.Shift({23, 42});
1016  },
1017  false, {23, 42}, "Shift");
1018 }

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::IsClosed(), 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() [235/465]

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

Definition at line 189 of file path_unittests.cc.

189  {
190  // Closed shapes.
191  {
192  Path path = PathBuilder{}.AddCircle({100, 100}, 50).TakePath();
193  ContourComponent contour;
194  path.GetContourComponentAtIndex(0, contour);
195  EXPECT_POINT_NEAR(contour.destination, Point(100, 50));
196  EXPECT_TRUE(contour.IsClosed());
197  }
198 
199  {
200  Path path =
201  PathBuilder{}.AddOval(Rect::MakeXYWH(100, 100, 100, 100)).TakePath();
202  ContourComponent contour;
203  path.GetContourComponentAtIndex(0, contour);
204  EXPECT_POINT_NEAR(contour.destination, Point(150, 100));
205  EXPECT_TRUE(contour.IsClosed());
206  }
207 
208  {
209  Path path =
210  PathBuilder{}.AddRect(Rect::MakeXYWH(100, 100, 100, 100)).TakePath();
211  ContourComponent contour;
212  path.GetContourComponentAtIndex(0, contour);
213  EXPECT_POINT_NEAR(contour.destination, Point(100, 100));
214  EXPECT_TRUE(contour.IsClosed());
215  }
216 
217  {
218  Path path = PathBuilder{}
219  .AddRoundRect(RoundRect::MakeRectRadius(
220  Rect::MakeXYWH(100, 100, 100, 100), 10))
221  .TakePath();
222  ContourComponent contour;
223  path.GetContourComponentAtIndex(0, contour);
224  EXPECT_POINT_NEAR(contour.destination, Point(110, 100));
225  EXPECT_TRUE(contour.IsClosed());
226  }
227 
228  {
229  Path path = PathBuilder{}
230  .AddRoundRect(RoundRect::MakeRectXY(
231  Rect::MakeXYWH(100, 100, 100, 100), Size(10, 20)))
232  .TakePath();
233  ContourComponent contour;
234  path.GetContourComponentAtIndex(0, contour);
235  EXPECT_POINT_NEAR(contour.destination, Point(110, 100));
236  EXPECT_TRUE(contour.IsClosed());
237  }
238 
239  // Open shapes.
240  {
241  Point p(100, 100);
242  Path path = PathBuilder{}.AddLine(p, {200, 100}).TakePath();
243  ContourComponent contour;
244  path.GetContourComponentAtIndex(0, contour);
245  ASSERT_POINT_NEAR(contour.destination, p);
246  ASSERT_FALSE(contour.IsClosed());
247  }
248 
249  {
250  Path path =
251  PathBuilder{}
252  .AddCubicCurve({100, 100}, {100, 50}, {100, 150}, {200, 100})
253  .TakePath();
254  ContourComponent contour;
255  path.GetContourComponentAtIndex(0, contour);
256  ASSERT_POINT_NEAR(contour.destination, Point(100, 100));
257  ASSERT_FALSE(contour.IsClosed());
258  }
259 
260  {
261  Path path = PathBuilder{}
262  .AddQuadraticCurve({100, 100}, {100, 50}, {200, 100})
263  .TakePath();
264  ContourComponent contour;
265  path.GetContourComponentAtIndex(0, contour);
266  ASSERT_POINT_NEAR(contour.destination, Point(100, 100));
267  ASSERT_FALSE(contour.IsClosed());
268  }
269 }

References impeller::PathBuilder::AddCircle(), impeller::PathBuilder::AddCubicCurve(), impeller::PathBuilder::AddLine(), impeller::PathBuilder::AddOval(), impeller::PathBuilder::AddQuadraticCurve(), impeller::PathBuilder::AddRect(), impeller::PathBuilder::AddRoundRect(), ASSERT_POINT_NEAR, impeller::ContourComponent::destination, EXPECT_POINT_NEAR, impeller::Path::GetContourComponentAtIndex(), impeller::ContourComponent::IsClosed(), impeller::RoundRect::MakeRectRadius(), impeller::RoundRect::MakeRectXY(), impeller::TRect< Scalar >::MakeXYWH(), and impeller::PathBuilder::TakePath().

◆ TEST() [236/465]

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

Definition at line 414 of file path_unittests.cc.

414  {
415  PathBuilder builder;
416  auto path_1 = builder.AddLine({0, 0}, {1, 1}).TakePath();
417 
418  ASSERT_EQ(path_1.GetBoundingBox().value_or(Rect::MakeMaximum()),
419  Rect::MakeLTRB(0, 0, 1, 1));
420 
421  auto path_2 = builder.AddLine({-1, -1}, {1, 1}).TakePath();
422 
423  // Verify that PathBuilder recomputes the bounds.
424  ASSERT_EQ(path_2.GetBoundingBox().value_or(Rect::MakeMaximum()),
425  Rect::MakeLTRB(-1, -1, 1, 1));
426 
427  // PathBuilder can set the bounds to whatever it wants
428  auto path_3 = builder.AddLine({0, 0}, {1, 1})
429  .SetBounds(Rect::MakeLTRB(0, 0, 100, 100))
430  .TakePath();
431 
432  ASSERT_EQ(path_3.GetBoundingBox().value_or(Rect::MakeMaximum()),
433  Rect::MakeLTRB(0, 0, 100, 100));
434 }

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

◆ TEST() [237/465]

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

Definition at line 34 of file path_unittests.cc.

34  {
35  PathBuilder builder;
36  builder.MoveTo({10, 10});
37  builder.LineTo({20, 20});
38  builder.LineTo({30, 30});
39  builder.MoveTo({40, 40});
40  builder.LineTo({50, 50});
41 
42  auto polyline = builder.TakePath().CreatePolyline(1.0f);
43 
44  ASSERT_EQ(polyline.contours.size(), 2u);
45  ASSERT_EQ(polyline.points->size(), 5u);
46  ASSERT_EQ(polyline.GetPoint(0).x, 10);
47  ASSERT_EQ(polyline.GetPoint(1).x, 20);
48  ASSERT_EQ(polyline.GetPoint(2).x, 30);
49  ASSERT_EQ(polyline.GetPoint(3).x, 40);
50  ASSERT_EQ(polyline.GetPoint(4).x, 50);
51 }

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

◆ TEST() [238/465]

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

Definition at line 271 of file path_unittests.cc.

271  {
272  Path::Polyline polyline = PathBuilder{}
273  .AddLine({100, 100}, {200, 100})
274  .MoveTo({100, 200})
275  .LineTo({150, 250})
276  .LineTo({200, 200})
277  .Close()
278  .TakePath()
279  .CreatePolyline(1.0f);
280  ASSERT_EQ(polyline.points->size(), 6u);
281  ASSERT_EQ(polyline.contours.size(), 2u);
282  ASSERT_EQ(polyline.contours[0].is_closed, false);
283  ASSERT_EQ(polyline.contours[0].start_index, 0u);
284  ASSERT_EQ(polyline.contours[1].is_closed, true);
285  ASSERT_EQ(polyline.contours[1].start_index, 2u);
286 }

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

◆ TEST() [239/465]

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

Definition at line 519 of file path_unittests.cc.

519  {
520  PathBuilder builder;
521  // Straight diagonal line.
522  builder.AddCubicCurve({0, 1}, {2, 3}, {4, 5}, {6, 7});
523  auto path = builder.TakePath();
524  auto actual = path.GetBoundingBox();
525  auto expected = Rect::MakeLTRB(0, 1, 6, 7);
526 
527  ASSERT_TRUE(actual.has_value());
528  ASSERT_RECT_NEAR(actual.value_or(Rect::MakeMaximum()), expected);
529 }

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

◆ TEST() [240/465]

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

Definition at line 436 of file path_unittests.cc.

436  {
437  PathBuilder builder;
438  auto path = builder.HorizontalLineTo(10).TakePath();
439 
440  LinearPathComponent linear;
441  path.GetLinearComponentAtIndex(1, linear);
442 
443  EXPECT_EQ(linear.p1, Point(0, 0));
444  EXPECT_EQ(linear.p2, Point(10, 0));
445 }

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

◆ TEST() [241/465]

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

Definition at line 322 of file path_unittests.cc.

322  {
323  Path::Polyline polyline =
324  PathBuilder{}
325  .MoveTo({50, 50})
326  .LineTo({50, 50}) // Insert duplicate at beginning of contour.
327  .LineTo({100, 50})
328  .LineTo({100, 50}) // Insert duplicate at contour join.
329  .LineTo({100, 100})
330  .Close() // Implicitly insert duplicate {50, 50} across contours.
331  .LineTo({0, 50})
332  .LineTo({0, 100})
333  .LineTo({0, 100}) // Insert duplicate at end of contour.
334  .TakePath()
335  .CreatePolyline(1.0f);
336  ASSERT_EQ(polyline.contours.size(), 2u);
337  ASSERT_EQ(polyline.contours[0].start_index, 0u);
338  ASSERT_TRUE(polyline.contours[0].is_closed);
339  ASSERT_EQ(polyline.contours[1].start_index, 4u);
340  ASSERT_FALSE(polyline.contours[1].is_closed);
341  ASSERT_EQ(polyline.points->size(), 7u);
342  ASSERT_EQ(polyline.GetPoint(0), Point(50, 50));
343  ASSERT_EQ(polyline.GetPoint(1), Point(100, 50));
344  ASSERT_EQ(polyline.GetPoint(2), Point(100, 100));
345  ASSERT_EQ(polyline.GetPoint(3), Point(50, 50));
346  ASSERT_EQ(polyline.GetPoint(4), Point(50, 50));
347  ASSERT_EQ(polyline.GetPoint(5), Point(0, 50));
348  ASSERT_EQ(polyline.GetPoint(6), Point(0, 100));
349 }

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

◆ TEST() [242/465]

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

Definition at line 378 of file path_unittests.cc.

378  {
379  PathBuilder builder{};
380  auto path =
381  builder.AddLine(Point(0, 0), Point(10, 10))
382  .AddQuadraticCurve(Point(10, 10), Point(15, 15), Point(20, 20))
383  .AddCubicCurve(Point(20, 20), Point(25, 25), Point(-5, -5),
384  Point(30, 30))
385  .Close()
386  .Shift(Point(1, 1))
387  .TakePath();
388 
389  ContourComponent contour;
390  LinearPathComponent linear;
391  QuadraticPathComponent quad;
392  CubicPathComponent cubic;
393 
394  ASSERT_TRUE(path.GetContourComponentAtIndex(0, contour));
395  ASSERT_TRUE(path.GetLinearComponentAtIndex(1, linear));
396  ASSERT_TRUE(path.GetQuadraticComponentAtIndex(3, quad));
397  ASSERT_TRUE(path.GetCubicComponentAtIndex(5, cubic));
398 
399  EXPECT_EQ(contour.destination, Point(1, 1));
400 
401  EXPECT_EQ(linear.p1, Point(1, 1));
402  EXPECT_EQ(linear.p2, Point(11, 11));
403 
404  EXPECT_EQ(quad.cp, Point(16, 16));
405  EXPECT_EQ(quad.p1, Point(11, 11));
406  EXPECT_EQ(quad.p2, Point(21, 21));
407 
408  EXPECT_EQ(cubic.cp1, Point(26, 26));
409  EXPECT_EQ(cubic.cp2, Point(-4, -4));
410  EXPECT_EQ(cubic.p1, Point(21, 21));
411  EXPECT_EQ(cubic.p2, Point(31, 31));
412 }

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

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

Definition at line 53 of file path_unittests.cc.

53  {
54  // Closed shapes.
55  {
56  Path path = PathBuilder{}.AddCircle({100, 100}, 50).TakePath();
57  EXPECT_TRUE(path.IsSingleContour());
58  }
59 
60  {
61  Path path =
62  PathBuilder{}.AddOval(Rect::MakeXYWH(100, 100, 100, 100)).TakePath();
63 
64  EXPECT_TRUE(path.IsSingleContour());
65  }
66 
67  {
68  Path path =
69  PathBuilder{}.AddRect(Rect::MakeXYWH(100, 100, 100, 100)).TakePath();
70 
71  EXPECT_TRUE(path.IsSingleContour());
72  }
73 
74  {
75  Path path = PathBuilder{}
76  .AddRoundRect(RoundRect::MakeRectRadius(
77  Rect::MakeXYWH(100, 100, 100, 100), 10))
78  .TakePath();
79 
80  EXPECT_TRUE(path.IsSingleContour());
81  }
82 
83  // Open shapes.
84  {
85  Point p(100, 100);
86  Path path = PathBuilder{}.AddLine(p, {200, 100}).TakePath();
87 
88  EXPECT_TRUE(path.IsSingleContour());
89  }
90 
91  {
92  Path path =
93  PathBuilder{}
94  .AddCubicCurve({100, 100}, {100, 50}, {100, 150}, {200, 100})
95  .TakePath();
96 
97  EXPECT_TRUE(path.IsSingleContour());
98  }
99 
100  {
101  Path path = PathBuilder{}
102  .AddQuadraticCurve({100, 100}, {100, 50}, {200, 100})
103  .TakePath();
104 
105  EXPECT_TRUE(path.IsSingleContour());
106  }
107 }

References impeller::PathBuilder::AddCircle(), impeller::PathBuilder::AddCubicCurve(), impeller::PathBuilder::AddLine(), impeller::PathBuilder::AddOval(), impeller::PathBuilder::AddQuadraticCurve(), impeller::PathBuilder::AddRect(), impeller::PathBuilder::AddRoundRect(), impeller::Path::IsSingleContour(), impeller::RoundRect::MakeRectRadius(), impeller::TRect< Scalar >::MakeXYWH(), and impeller::PathBuilder::TakePath().

◆ TEST() [244/465]

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

Definition at line 109 of file path_unittests.cc.

109  {
110  // Closed shapes.
111  {
112  Path path = PathBuilder{}
113  .AddCircle({100, 100}, 50)
114  .AddCircle({100, 100}, 50)
115  .TakePath();
116  EXPECT_FALSE(path.IsSingleContour());
117  }
118 
119  {
120  Path path = PathBuilder{}
121  .AddOval(Rect::MakeXYWH(100, 100, 100, 100))
122  .AddOval(Rect::MakeXYWH(100, 100, 100, 100))
123  .TakePath();
124 
125  EXPECT_FALSE(path.IsSingleContour());
126  }
127 
128  {
129  Path path = PathBuilder{}
130  .AddRect(Rect::MakeXYWH(100, 100, 100, 100))
131  .AddRect(Rect::MakeXYWH(100, 100, 100, 100))
132  .TakePath();
133 
134  EXPECT_FALSE(path.IsSingleContour());
135  }
136 
137  {
138  Path path = PathBuilder{}
139  .AddRoundRect(RoundRect::MakeRectRadius(
140  Rect::MakeXYWH(100, 100, 100, 100), 10))
141  .AddRoundRect(RoundRect::MakeRectRadius(
142  Rect::MakeXYWH(100, 100, 100, 100), 10))
143  .TakePath();
144 
145  EXPECT_FALSE(path.IsSingleContour());
146  }
147 
148  {
149  Path path = PathBuilder{}
150  .AddRoundRect(RoundRect::MakeRectXY(
151  Rect::MakeXYWH(100, 100, 100, 100), Size(10, 20)))
152  .AddRoundRect(RoundRect::MakeRectXY(
153  Rect::MakeXYWH(100, 100, 100, 100), Size(10, 20)))
154  .TakePath();
155 
156  EXPECT_FALSE(path.IsSingleContour());
157  }
158 
159  // Open shapes.
160  {
161  Point p(100, 100);
162  Path path =
163  PathBuilder{}.AddLine(p, {200, 100}).AddLine(p, {200, 100}).TakePath();
164 
165  EXPECT_FALSE(path.IsSingleContour());
166  }
167 
168  {
169  Path path =
170  PathBuilder{}
171  .AddCubicCurve({100, 100}, {100, 50}, {100, 150}, {200, 100})
172  .AddCubicCurve({100, 100}, {100, 50}, {100, 150}, {200, 100})
173  .TakePath();
174 
175  EXPECT_FALSE(path.IsSingleContour());
176  }
177 
178  {
179  Path path = PathBuilder{}
180  .AddQuadraticCurve({100, 100}, {100, 50}, {200, 100})
181  .Close()
182  .AddQuadraticCurve({100, 100}, {100, 50}, {200, 100})
183  .TakePath();
184 
185  EXPECT_FALSE(path.IsSingleContour());
186  }
187 }

References impeller::PathBuilder::AddCircle(), impeller::PathBuilder::AddCubicCurve(), impeller::PathBuilder::AddLine(), impeller::PathBuilder::AddOval(), impeller::PathBuilder::AddQuadraticCurve(), impeller::PathBuilder::AddRect(), impeller::PathBuilder::AddRoundRect(), impeller::Close(), impeller::Path::IsSingleContour(), impeller::RoundRect::MakeRectRadius(), impeller::RoundRect::MakeRectXY(), impeller::TRect< Scalar >::MakeXYWH(), and impeller::PathBuilder::TakePath().

◆ TEST() [245/465]

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

Definition at line 447 of file path_unittests.cc.

447  {
448  PathBuilder builder;
449  auto path = builder.VerticalLineTo(10).TakePath();
450 
451  LinearPathComponent linear;
452  path.GetLinearComponentAtIndex(1, linear);
453 
454  EXPECT_EQ(linear.p1, Point(0, 0));
455  EXPECT_EQ(linear.p2, Point(0, 10));
456 }

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

◆ TEST() [246/465]

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

Definition at line 351 of file path_unittests.cc.

351  {
352  auto point_buffer = std::make_unique<std::vector<Point>>();
353  auto point_buffer_address = reinterpret_cast<uintptr_t>(point_buffer.get());
354  Path::Polyline polyline =
355  PathBuilder{}
356  .MoveTo({50, 50})
357  .LineTo({100, 100})
358  .TakePath()
359  .CreatePolyline(
360  1.0f, std::move(point_buffer),
361  [point_buffer_address](
362  Path::Polyline::PointBufferPtr point_buffer) {
363  ASSERT_EQ(point_buffer->size(), 0u);
364  ASSERT_EQ(point_buffer_address,
365  reinterpret_cast<uintptr_t>(point_buffer.get()));
366  });
367 }

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

◆ TEST() [247/465]

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

Definition at line 369 of file path_unittests.cc.

369  {
370  EXPECT_DEATH_IF_SUPPORTED(PathBuilder{}
371  .MoveTo({50, 50})
372  .LineTo({100, 100})
373  .TakePath()
374  .CreatePolyline(1.0f, nullptr),
375  "");
376 }

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

◆ TEST() [248/465]

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

Definition at line 288 of file path_unittests.cc.

288  {
289  Path::Polyline polyline = PathBuilder{}
290  .AddLine({100, 100}, {200, 100})
291  .MoveTo({100, 200})
292  .LineTo({150, 250})
293  .LineTo({200, 200})
294  .Close()
295  .TakePath()
296  .CreatePolyline(1.0f);
297  size_t a1, a2, b1, b2;
298  std::tie(a1, a2) = polyline.GetContourPointBounds(0);
299  std::tie(b1, b2) = polyline.GetContourPointBounds(1);
300  ASSERT_EQ(a1, 0u);
301  ASSERT_EQ(a2, 2u);
302  ASSERT_EQ(b1, 2u);
303  ASSERT_EQ(b2, 6u);
304 }

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

◆ TEST() [249/465]

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

Definition at line 458 of file path_unittests.cc.

458  {
459  PathBuilder builder;
460  auto path = builder.QuadraticCurveTo(Point(10, 10), Point(20, 20)).TakePath();
461 
462  QuadraticPathComponent quad;
463  path.GetQuadraticComponentAtIndex(1, quad);
464 
465  EXPECT_EQ(quad.p1, Point(0, 0));
466  EXPECT_EQ(quad.cp, Point(10, 10));
467  EXPECT_EQ(quad.p2, Point(20, 20));
468 }

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

◆ TEST() [250/465]

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

Definition at line 622 of file path_unittests.cc.

622  {
623  PathBuilder builder;
624  auto path = builder.LineTo({0, 10})
625  .LineTo({10, 10})
626  .Close() // Returns to (0, 0)
627  .Close() // No Op
628  .Close() // Still No op
629  .TakePath();
630 
631  EXPECT_EQ(path.GetComponentCount(), 5u);
632  EXPECT_EQ(path.GetComponentCount(Path::ComponentType::kLinear), 3u);
633  EXPECT_EQ(path.GetComponentCount(Path::ComponentType::kContour), 2u);
634 }

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

◆ TEST() [251/465]

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

Definition at line 544 of file path_unittests.cc.

544  {
545  PathBuilder builder;
546 
547  auto path = builder.AddLine({0, 0}, {100, 100})
548  .AddQuadraticCurve({100, 100}, {200, 200}, {300, 300})
549  .AddCubicCurve({300, 300}, {400, 400}, {500, 500}, {600, 600})
550  .TakePath();
551 
552  EXPECT_EQ(path.GetComponentCount(), 6u);
553  EXPECT_EQ(path.GetComponentCount(Path::ComponentType::kLinear), 1u);
554  EXPECT_EQ(path.GetComponentCount(Path::ComponentType::kQuadratic), 1u);
555  EXPECT_EQ(path.GetComponentCount(Path::ComponentType::kCubic), 1u);
556  EXPECT_EQ(path.GetComponentCount(Path::ComponentType::kContour), 3u);
557 
558  {
559  LinearPathComponent linear;
560  EXPECT_TRUE(path.GetLinearComponentAtIndex(1, linear));
561 
562  Point p1(0, 0);
563  Point p2(100, 100);
564  EXPECT_EQ(linear.p1, p1);
565  EXPECT_EQ(linear.p2, p2);
566  }
567 
568  {
569  QuadraticPathComponent quad;
570  EXPECT_TRUE(path.GetQuadraticComponentAtIndex(3, quad));
571 
572  Point p1(100, 100);
573  Point cp(200, 200);
574  Point p2(300, 300);
575  EXPECT_EQ(quad.p1, p1);
576  EXPECT_EQ(quad.cp, cp);
577  EXPECT_EQ(quad.p2, p2);
578  }
579 
580  {
581  CubicPathComponent cubic;
582  EXPECT_TRUE(path.GetCubicComponentAtIndex(5, cubic));
583 
584  Point p1(300, 300);
585  Point cp1(400, 400);
586  Point cp2(500, 500);
587  Point p2(600, 600);
588  EXPECT_EQ(cubic.p1, p1);
589  EXPECT_EQ(cubic.cp1, cp1);
590  EXPECT_EQ(cubic.cp2, cp2);
591  EXPECT_EQ(cubic.p2, p2);
592  }
593 
594  {
595  ContourComponent contour;
596  EXPECT_TRUE(path.GetContourComponentAtIndex(0, contour));
597 
598  Point p1(0, 0);
599  EXPECT_EQ(contour.destination, p1);
600  EXPECT_FALSE(contour.IsClosed());
601  }
602 
603  {
604  ContourComponent contour;
605  EXPECT_TRUE(path.GetContourComponentAtIndex(2, contour));
606 
607  Point p1(100, 100);
608  EXPECT_EQ(contour.destination, p1);
609  EXPECT_FALSE(contour.IsClosed());
610  }
611 
612  {
613  ContourComponent contour;
614  EXPECT_TRUE(path.GetContourComponentAtIndex(4, contour));
615 
616  Point p1(300, 300);
617  EXPECT_EQ(contour.destination, p1);
618  EXPECT_FALSE(contour.IsClosed());
619  }
620 }

References impeller::PathBuilder::AddLine(), impeller::QuadraticPathComponent::cp, impeller::CubicPathComponent::cp1, impeller::CubicPathComponent::cp2, impeller::ContourComponent::destination, impeller::ContourComponent::IsClosed(), impeller::Path::kContour, impeller::Path::kCubic, impeller::Path::kLinear, impeller::Path::kQuadratic, impeller::LinearPathComponent::p1, impeller::QuadraticPathComponent::p1, impeller::CubicPathComponent::p1, impeller::LinearPathComponent::p2, impeller::QuadraticPathComponent::p2, and impeller::CubicPathComponent::p2.

◆ TEST() [252/465]

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

Definition at line 784 of file path_unittests.cc.

784  {
785  Path path = PathBuilder{}
786  .AddRoundRect(RoundRect::MakeRectRadius(
787  Rect::MakeLTRB(0, 0, 100, 100), 10))
788  .TakePath();
789  auto [points, contours] = path.CountStorage(1.0);
790 
791  std::vector<Point> point_storage(points);
792  std::vector<uint16_t> index_storage(points + (contours - 1));
793 
794  StripVertexWriter writer(point_storage.data(), index_storage.data());
795  path.WritePolyline(1.0, writer);
796 
797  EXPECT_LE(writer.GetIndexCount(), index_storage.size());
798  EXPECT_EQ(point_storage[0], Point(10, 0));
799 }

References impeller::PathBuilder::AddRoundRect(), impeller::Path::CountStorage(), impeller::StripVertexWriter::GetIndexCount(), impeller::TRect< Scalar >::MakeLTRB(), impeller::RoundRect::MakeRectRadius(), impeller::PathBuilder::TakePath(), and impeller::Path::WritePolyline().

◆ TEST() [253/465]

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

Definition at line 801 of file path_unittests.cc.

801  {
802  PathBuilder builder{};
803  for (auto i = 0; i < 10; i++) {
804  builder.AddRoundRect(
805  RoundRect::MakeRectRadius(Rect::MakeLTRB(0 + i, 0 + i, 100, 100), 10));
806  }
807  auto path = builder.TakePath();
808  auto [points, contours] = path.CountStorage(1.0);
809 
810  std::vector<Point> point_storage(points);
811  std::vector<uint16_t> index_storage(points + (contours - 1));
812 
813  StripVertexWriter writer(point_storage.data(), index_storage.data());
814  path.WritePolyline(1.0, writer);
815 
816  EXPECT_LE(writer.GetIndexCount(), index_storage.size());
817  EXPECT_EQ(point_storage[0], Point(10, 0));
818 }

References impeller::PathBuilder::AddRoundRect(), impeller::Path::CountStorage(), impeller::StripVertexWriter::GetIndexCount(), impeller::TRect< Scalar >::MakeLTRB(), impeller::RoundRect::MakeRectRadius(), and impeller::PathBuilder::TakePath().

◆ TEST() [254/465]

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

Definition at line 741 of file path_unittests.cc.

741  {
742  // Create a rectangle that lacks an explicit close.
743  Path path = PathBuilder{}
744  .LineTo({100, 0})
745  .LineTo({100, 100})
746  .LineTo({0, 100})
747  .TakePath();
748 
749  std::vector<Point> expected = {{0, 0}, {100, 0}, {100, 100},
750  {0, 100}, {0, 0}, {0, 0}};
751  std::vector<uint16_t> expected_indices = {0, 1, 3, 2, 0xFFFF, 0};
752 
753  auto [points, contours] = path.CountStorage(1.0);
754 
755  std::vector<Point> point_storage(points);
756  std::vector<uint16_t> index_storage(points + (contours - 1));
757 
758  StripVertexWriter writer(point_storage.data(), index_storage.data());
759  path.WritePolyline(1.0, writer);
760 
761  EXPECT_LE(index_storage, expected_indices);
762  EXPECT_EQ(point_storage, expected);
763 }

References impeller::Path::CountStorage(), impeller::LineTo(), impeller::PathBuilder::LineTo(), and impeller::Path::WritePolyline().

◆ TEST() [255/465]

impeller::testing::TEST ( PipelineCacheDataVKTest  ,
CanCreateFromDeviceProperties   
)

Definition at line 76 of file pipeline_cache_data_vk_unittests.cc.

76  {
77  vk::PhysicalDeviceProperties props;
78  std::array<uint8_t, 16> uuid{
79  0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
80  };
81  props.pipelineCacheUUID = uuid;
82  props.deviceID = 10;
83  props.vendorID = 11;
84  props.driverVersion = 12;
85  PipelineCacheHeaderVK header(props, 99);
86  EXPECT_EQ(uuid.size(), std::size(header.uuid));
87  EXPECT_EQ(props.deviceID, header.device_id);
88  EXPECT_EQ(props.vendorID, header.vendor_id);
89  EXPECT_EQ(props.driverVersion, header.driver_version);
90  for (size_t i = 0; i < uuid.size(); i++) {
91  EXPECT_EQ(header.uuid[i], uuid.at(i));
92  }
93 }

References impeller::PipelineCacheHeaderVK::device_id, impeller::PipelineCacheHeaderVK::driver_version, impeller::PipelineCacheHeaderVK::uuid, and impeller::PipelineCacheHeaderVK::vendor_id.

◆ TEST() [256/465]

impeller::testing::TEST ( PipelineCacheDataVKTest  ,
CanTestHeaderCompatibility   
)

Definition at line 16 of file pipeline_cache_data_vk_unittests.cc.

16  {
17  {
18  PipelineCacheHeaderVK a;
19  PipelineCacheHeaderVK b;
20  EXPECT_EQ(a.abi, sizeof(void*));
21 #ifdef FML_ARCH_CPU_64_BITS
22  EXPECT_EQ(a.abi, 8u);
23 #elif FML_ARCH_CPU_32_BITS
24  EXPECT_EQ(a.abi, 4u);
25 #endif
26  EXPECT_TRUE(a.IsCompatibleWith(b));
27  }
28  // Different data sizes don't matter.
29  {
30  PipelineCacheHeaderVK a;
31  PipelineCacheHeaderVK b;
32  a.data_size = b.data_size + 100u;
33  EXPECT_TRUE(a.IsCompatibleWith(b));
34  }
35  // Magic, Driver, vendor, ABI, and UUID matter.
36  {
37  PipelineCacheHeaderVK a;
38  PipelineCacheHeaderVK b;
39  b.magic = 100;
40  EXPECT_FALSE(a.IsCompatibleWith(b));
41  }
42  {
43  PipelineCacheHeaderVK a;
44  PipelineCacheHeaderVK b;
45  b.driver_version = 100;
46  EXPECT_FALSE(a.IsCompatibleWith(b));
47  }
48  {
49  PipelineCacheHeaderVK a;
50  PipelineCacheHeaderVK b;
51  b.vendor_id = 100;
52  EXPECT_FALSE(a.IsCompatibleWith(b));
53  }
54  {
55  PipelineCacheHeaderVK a;
56  PipelineCacheHeaderVK b;
57  b.device_id = 100;
58  EXPECT_FALSE(a.IsCompatibleWith(b));
59  }
60  {
61  PipelineCacheHeaderVK a;
62  PipelineCacheHeaderVK b;
63  b.abi = a.abi / 2u;
64  EXPECT_FALSE(a.IsCompatibleWith(b));
65  }
66  {
67  PipelineCacheHeaderVK a;
68  PipelineCacheHeaderVK b;
69  for (size_t i = 0; i < VK_UUID_SIZE; i++) {
70  b.uuid[i] = a.uuid[i] + 1;
71  }
72  EXPECT_FALSE(a.IsCompatibleWith(b));
73  }
74 }

References impeller::PipelineCacheHeaderVK::abi, impeller::saturated::b, impeller::PipelineCacheHeaderVK::data_size, impeller::PipelineCacheHeaderVK::IsCompatibleWith(), and impeller::PipelineCacheHeaderVK::uuid.

◆ TEST() [257/465]

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

impeller::testing::TEST ( PoolTest  ,
Overload   
)

Definition at line 47 of file pool_unittests.cc.

47  {
48  Pool<Foobar> pool(1'000);
49  {
50  std::vector<std::shared_ptr<Foobar>> values;
51  values.reserve(20);
52  for (int i = 0; i < 20; i++) {
53  values.push_back(pool.Grab());
54  }
55  for (const auto& value : values) {
56  value->SetSize(100);
57  pool.Recycle(value);
58  }
59  }
60  EXPECT_EQ(pool.GetSize(), 1'000u);
61 }

References impeller::Pool< T >::GetSize(), impeller::Pool< T >::Grab(), impeller::Pool< T >::Recycle(), and value.

◆ TEST() [259/465]

impeller::testing::TEST ( PoolTest  ,
Simple   
)

Definition at line 33 of file pool_unittests.cc.

33  {
34  Pool<Foobar> pool(1'000);
35  {
36  auto grabbed = pool.Grab();
37  grabbed->SetSize(123);
38  pool.Recycle(grabbed);
39  EXPECT_EQ(pool.GetSize(), 123u);
40  }
41  auto grabbed = pool.Grab();
42  EXPECT_EQ(grabbed->GetSize(), 123u);
43  EXPECT_TRUE(grabbed->GetIsReset());
44  EXPECT_EQ(pool.GetSize(), 0u);
45 }

References impeller::Pool< T >::GetSize(), impeller::Pool< T >::Grab(), and impeller::Pool< T >::Recycle().

◆ TEST() [260/465]

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

Definition at line 1316 of file rect_unittests.cc.

1316  {
1317  auto rect1 =
1318  Rect::MakeXYWH(472.599945f, 440.999969f, 1102.80005f, 654.000061f);
1319  auto rect2 = Rect::MakeXYWH(724.f, 618.f, 600.f, 300.f);
1320  EXPECT_TRUE(rect1.Contains(rect2));
1321 }

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

◆ TEST() [261/465]

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

Definition at line 899 of file rect_unittests.cc.

899  {
900  IRect rect = IRect::MakeLTRB(50, 50, 100, 100);
901 
902  auto test = [&rect](int64_t l, int64_t t, int64_t r, int64_t b,
903  const std::string& label) {
904  EXPECT_FALSE(IRect::MakeLTRB(l, b, r, t).IntersectsWithRect(rect))
905  << label << " with Top/Bottom swapped";
906  EXPECT_FALSE(IRect::MakeLTRB(r, b, l, t).IntersectsWithRect(rect))
907  << label << " with Left/Right swapped";
908  EXPECT_FALSE(IRect::MakeLTRB(r, t, l, b).IntersectsWithRect(rect))
909  << label << " with all sides swapped";
910  };
911 
912  test(20, 20, 30, 30, "Above and Left");
913  test(70, 20, 80, 30, "Above");
914  test(120, 20, 130, 30, "Above and Right");
915  test(120, 70, 130, 80, "Right");
916  test(120, 120, 130, 130, "Below and Right");
917  test(70, 120, 80, 130, "Below");
918  test(20, 120, 30, 130, "Below and Left");
919  test(20, 70, 30, 80, "Left");
920 
921  test(70, 70, 80, 80, "Inside");
922 
923  test(40, 70, 60, 80, "Straddling Left");
924  test(70, 40, 80, 60, "Straddling Top");
925  test(90, 70, 110, 80, "Straddling Right");
926  test(70, 90, 80, 110, "Straddling Bottom");
927 }
IRect64 IRect
Definition: rect.h:795

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

◆ TEST() [262/465]

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

Definition at line 869 of file rect_unittests.cc.

869  {
870  Rect rect = Rect::MakeLTRB(50, 50, 100, 100);
871 
872  auto test = [&rect](Scalar l, Scalar t, Scalar r, Scalar b,
873  const std::string& label) {
874  EXPECT_FALSE(Rect::MakeLTRB(l, b, r, t).IntersectsWithRect(rect))
875  << label << " with Top/Bottom swapped";
876  EXPECT_FALSE(Rect::MakeLTRB(r, b, l, t).IntersectsWithRect(rect))
877  << label << " with Left/Right swapped";
878  EXPECT_FALSE(Rect::MakeLTRB(r, t, l, b).IntersectsWithRect(rect))
879  << label << " with all sides swapped";
880  };
881 
882  test(20, 20, 30, 30, "Above and Left");
883  test(70, 20, 80, 30, "Above");
884  test(120, 20, 130, 30, "Above and Right");
885  test(120, 70, 130, 80, "Right");
886  test(120, 120, 130, 130, "Below and Right");
887  test(70, 120, 80, 130, "Below");
888  test(20, 120, 30, 130, "Below and Left");
889  test(20, 70, 30, 80, "Left");
890 
891  test(70, 70, 80, 80, "Inside");
892 
893  test(40, 70, 60, 80, "Straddling Left");
894  test(70, 40, 80, 60, "Straddling Top");
895  test(90, 70, 110, 80, "Straddling Right");
896  test(70, 90, 80, 110, "Straddling Bottom");
897 }

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

◆ TEST() [263/465]

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

Definition at line 1239 of file rect_unittests.cc.

1239  {
1240  EXPECT_EQ(Rect::MakeXYWH(10, 30, 20, 20).GetCenter(), Point(20, 40));
1241  EXPECT_EQ(Rect::MakeXYWH(10, 30, 20, 19).GetCenter(), Point(20, 39.5));
1242  EXPECT_EQ(Rect::MakeMaximum().GetCenter(), Point(0, 0));
1243 
1244  // Note that we expect a Point as the answer from an IRect
1245  EXPECT_EQ(IRect::MakeXYWH(10, 30, 20, 20).GetCenter(), Point(20, 40));
1246  EXPECT_EQ(IRect::MakeXYWH(10, 30, 20, 19).GetCenter(), Point(20, 39.5));
1247  EXPECT_EQ(IRect::MakeMaximum().GetCenter(), Point(0, 0));
1248 }

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

◆ TEST() [264/465]

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

Definition at line 1025 of file rect_unittests.cc.

1025  {
1026  EXPECT_EQ(IRect::MakeXYWH(0, 0, 100, 200).Area(), 20000);
1027  EXPECT_EQ(IRect::MakeXYWH(10, 20, 100, 200).Area(), 20000);
1028  EXPECT_EQ(IRect::MakeXYWH(0, 0, 200, 100).Area(), 20000);
1029  EXPECT_EQ(IRect::MakeXYWH(10, 20, 200, 100).Area(), 20000);
1030  EXPECT_EQ(IRect::MakeXYWH(0, 0, 100, 100).Area(), 10000);
1031  EXPECT_EQ(IRect::MakeXYWH(10, 20, 100, 100).Area(), 10000);
1032 }

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

◆ TEST() [265/465]

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

Definition at line 2404 of file rect_unittests.cc.

2404  {
2405  auto check_empty_flips = [](const IRect& rect, const IPoint& point,
2406  const std::string& label) {
2407  ASSERT_FALSE(rect.IsEmpty());
2408 
2409  EXPECT_FALSE(flip_lr(rect).ContainsInclusive(point)) << label;
2410  EXPECT_FALSE(flip_tb(rect).ContainsInclusive(point)) << label;
2411  EXPECT_FALSE(flip_lrtb(rect).ContainsInclusive(point)) << label;
2412  };
2413 
2414  auto test_inside = [&check_empty_flips](const IRect& rect,
2415  const IPoint& point) {
2416  ASSERT_FALSE(rect.IsEmpty()) << rect;
2417 
2418  std::stringstream stream;
2419  stream << rect << " contains " << point;
2420  auto label = stream.str();
2421 
2422  EXPECT_TRUE(rect.ContainsInclusive(point)) << label;
2423  check_empty_flips(rect, point, label);
2424  };
2425 
2426  auto test_outside = [&check_empty_flips](const IRect& rect,
2427  const IPoint& point) {
2428  ASSERT_FALSE(rect.IsEmpty()) << rect;
2429 
2430  std::stringstream stream;
2431  stream << rect << " contains " << point;
2432  auto label = stream.str();
2433 
2434  EXPECT_FALSE(rect.ContainsInclusive(point)) << label;
2435  check_empty_flips(rect, point, label);
2436  };
2437 
2438  {
2439  // Origin is inclusive
2440  auto r = IRect::MakeXYWH(100, 100, 100, 100);
2441  auto p = IPoint(100, 100);
2442 
2443  test_inside(r, p);
2444  }
2445  {
2446  // Size is inclusive
2447  auto r = IRect::MakeXYWH(100, 100, 100, 100);
2448  auto p = IPoint(200, 200);
2449 
2450  test_inside(r, p);
2451  }
2452  {
2453  // Size + "epsilon" is exclusive
2454  auto r = IRect::MakeXYWH(100, 100, 100, 100);
2455  auto p = IPoint(201, 201);
2456 
2457  test_outside(r, p);
2458  }
2459  {
2460  auto r = IRect::MakeXYWH(100, 100, 100, 100);
2461  auto p = IPoint(99, 99);
2462 
2463  test_outside(r, p);
2464  }
2465  {
2466  auto r = IRect::MakeXYWH(100, 100, 100, 100);
2467  auto p = IPoint(199, 199);
2468 
2469  test_inside(r, p);
2470  }
2471 
2472  {
2473  auto r = IRect::MakeMaximum();
2474  auto p = IPoint(199, 199);
2475 
2476  test_inside(r, p);
2477  }
2478 }
static constexpr R flip_lrtb(R rect)

References impeller::TRect< T >::ContainsInclusive(), flip_lr(), flip_lrtb(), flip_tb(), impeller::TRect< T >::IsEmpty(), impeller::TRect< T >::MakeMaximum(), and impeller::TRect< T >::MakeXYWH().

◆ TEST() [266/465]

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

Definition at line 2242 of file rect_unittests.cc.

2242  {
2243  auto check_empty_flips = [](const IRect& rect, const IPoint& point,
2244  const std::string& label) {
2245  ASSERT_FALSE(rect.IsEmpty());
2246 
2247  EXPECT_FALSE(flip_lr(rect).Contains(point)) << label;
2248  EXPECT_FALSE(flip_tb(rect).Contains(point)) << label;
2249  EXPECT_FALSE(flip_lrtb(rect).Contains(point)) << label;
2250  };
2251 
2252  auto test_inside = [&check_empty_flips](const IRect& rect,
2253  const IPoint& point) {
2254  ASSERT_FALSE(rect.IsEmpty()) << rect;
2255 
2256  std::stringstream stream;
2257  stream << rect << " contains " << point;
2258  auto label = stream.str();
2259 
2260  EXPECT_TRUE(rect.Contains(point)) << label;
2261  check_empty_flips(rect, point, label);
2262  };
2263 
2264  auto test_outside = [&check_empty_flips](const IRect& rect,
2265  const IPoint& point) {
2266  ASSERT_FALSE(rect.IsEmpty()) << rect;
2267 
2268  std::stringstream stream;
2269  stream << rect << " contains " << point;
2270  auto label = stream.str();
2271 
2272  EXPECT_FALSE(rect.Contains(point)) << label;
2273  check_empty_flips(rect, point, label);
2274  };
2275 
2276  {
2277  // Origin is inclusive
2278  auto r = IRect::MakeXYWH(100, 100, 100, 100);
2279  auto p = IPoint(100, 100);
2280 
2281  test_inside(r, p);
2282  }
2283  {
2284  // Size is exclusive
2285  auto r = IRect::MakeXYWH(100, 100, 100, 100);
2286  auto p = IPoint(200, 200);
2287 
2288  test_outside(r, p);
2289  }
2290  {
2291  auto r = IRect::MakeXYWH(100, 100, 100, 100);
2292  auto p = IPoint(99, 99);
2293 
2294  test_outside(r, p);
2295  }
2296  {
2297  auto r = IRect::MakeXYWH(100, 100, 100, 100);
2298  auto p = IPoint(199, 199);
2299 
2300  test_inside(r, p);
2301  }
2302 
2303  {
2304  auto r = IRect::MakeMaximum();
2305  auto p = IPoint(199, 199);
2306 
2307  test_inside(r, p);
2308  }
2309 }

References impeller::TRect< T >::Contains(), flip_lr(), flip_lrtb(), flip_tb(), impeller::TRect< T >::IsEmpty(), impeller::TRect< T >::MakeMaximum(), and impeller::TRect< T >::MakeXYWH().

◆ TEST() [267/465]

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

Definition at line 2595 of file rect_unittests.cc.

2595  {
2596  auto check_empty_flips = [](const IRect& a, const IRect& b,
2597  const std::string& label) {
2598  ASSERT_FALSE(a.IsEmpty());
2599  // test b rects are allowed to have 0 w/h, but not be backwards
2600  ASSERT_FALSE(b.GetLeft() > b.GetRight() || b.GetTop() > b.GetBottom());
2601 
2602  // unflipped a vs flipped (empty) b yields true
2603  EXPECT_TRUE(a.Contains(flip_lr(b))) << label;
2604  EXPECT_TRUE(a.Contains(flip_tb(b))) << label;
2605  EXPECT_TRUE(a.Contains(flip_lrtb(b))) << label;
2606 
2607  // flipped (empty) a vs unflipped b yields false
2608  EXPECT_FALSE(flip_lr(a).Contains(b)) << label;
2609  EXPECT_FALSE(flip_tb(a).Contains(b)) << label;
2610  EXPECT_FALSE(flip_lrtb(a).Contains(b)) << label;
2611 
2612  // flipped (empty) a vs flipped (empty) b yields empty
2613  EXPECT_FALSE(flip_lr(a).Contains(flip_lr(b))) << label;
2614  EXPECT_FALSE(flip_tb(a).Contains(flip_tb(b))) << label;
2615  EXPECT_FALSE(flip_lrtb(a).Contains(flip_lrtb(b))) << label;
2616  };
2617 
2618  auto test_inside = [&check_empty_flips](const IRect& a, const IRect& b) {
2619  ASSERT_FALSE(a.IsEmpty()) << a;
2620  // test b rects are allowed to have 0 w/h, but not be backwards
2621  ASSERT_FALSE(b.GetLeft() > b.GetRight() || b.GetTop() > b.GetBottom());
2622 
2623  std::stringstream stream;
2624  stream << a << " contains " << b;
2625  auto label = stream.str();
2626 
2627  EXPECT_TRUE(a.Contains(b)) << label;
2628  check_empty_flips(a, b, label);
2629  };
2630 
2631  auto test_not_inside = [&check_empty_flips](const IRect& a, const IRect& b) {
2632  ASSERT_FALSE(a.IsEmpty()) << a;
2633  // If b was empty, it would be contained and should not be tested with
2634  // this function - use |test_inside| instead.
2635  ASSERT_FALSE(b.IsEmpty()) << b;
2636 
2637  std::stringstream stream;
2638  stream << a << " contains " << b;
2639  auto label = stream.str();
2640 
2641  EXPECT_FALSE(a.Contains(b)) << label;
2642  check_empty_flips(a, b, label);
2643  };
2644 
2645  {
2646  auto a = IRect::MakeXYWH(100, 100, 100, 100);
2647 
2648  test_inside(a, a);
2649  }
2650  {
2651  auto a = IRect::MakeXYWH(100, 100, 100, 100);
2652  auto b = IRect::MakeXYWH(0, 0, 0, 0);
2653 
2654  test_inside(a, b);
2655  }
2656  {
2657  auto a = IRect::MakeXYWH(100, 100, 100, 100);
2658  auto b = IRect::MakeXYWH(150, 150, 20, 20);
2659 
2660  test_inside(a, b);
2661  }
2662  {
2663  auto a = IRect::MakeXYWH(100, 100, 100, 100);
2664  auto b = IRect::MakeXYWH(150, 150, 100, 100);
2665 
2666  test_not_inside(a, b);
2667  }
2668  {
2669  auto a = IRect::MakeXYWH(100, 100, 100, 100);
2670  auto b = IRect::MakeXYWH(50, 50, 100, 100);
2671 
2672  test_not_inside(a, b);
2673  }
2674  {
2675  auto a = IRect::MakeXYWH(100, 100, 100, 100);
2676  auto b = IRect::MakeXYWH(0, 0, 300, 300);
2677 
2678  test_not_inside(a, b);
2679  }
2680  {
2681  auto a = IRect::MakeMaximum();
2682  auto b = IRect::MakeXYWH(0, 0, 300, 300);
2683 
2684  test_inside(a, b);
2685  }
2686 }

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

◆ TEST() [268/465]

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

Definition at line 686 of file rect_unittests.cc.

686  {
687  IRect rect = IRect::MakeLTRB(5, 10, 20, 25);
688  IRect copy = rect;
689 
690  EXPECT_EQ(rect, copy);
691  EXPECT_EQ(copy.GetLeft(), 5);
692  EXPECT_EQ(copy.GetTop(), 10);
693  EXPECT_EQ(copy.GetRight(), 20);
694  EXPECT_EQ(copy.GetBottom(), 25);
695  EXPECT_EQ(copy.GetX(), 5);
696  EXPECT_EQ(copy.GetY(), 10);
697  EXPECT_EQ(copy.GetWidth(), 15);
698  EXPECT_EQ(copy.GetHeight(), 15);
699  EXPECT_FALSE(copy.IsEmpty());
700 }

References impeller::TRect< T >::GetBottom(), impeller::TRect< T >::GetHeight(), impeller::TRect< T >::GetLeft(), impeller::TRect< T >::GetRight(), impeller::TRect< T >::GetTop(), impeller::TRect< T >::GetWidth(), impeller::TRect< T >::GetX(), impeller::TRect< T >::GetY(), impeller::TRect< T >::IsEmpty(), and impeller::TRect< T >::MakeLTRB().

◆ TEST() [269/465]

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

Definition at line 2840 of file rect_unittests.cc.

2840  {
2841  IRect cull_rect = IRect::MakeLTRB(20, 20, 40, 40);
2842 
2843  auto check_empty_flips = [&cull_rect](const IRect& diff_rect,
2844  const std::string& label) {
2845  EXPECT_FALSE(diff_rect.IsEmpty());
2846  EXPECT_FALSE(cull_rect.IsEmpty());
2847 
2848  // unflipped cull_rect vs flipped(empty) diff_rect
2849  // == cull_rect
2850  EXPECT_TRUE(cull_rect.Cutout(flip_lr(diff_rect)).has_value()) << label;
2851  EXPECT_EQ(cull_rect.Cutout(flip_lr(diff_rect)), cull_rect) << label;
2852  EXPECT_TRUE(cull_rect.Cutout(flip_tb(diff_rect)).has_value()) << label;
2853  EXPECT_EQ(cull_rect.Cutout(flip_tb(diff_rect)), cull_rect) << label;
2854  EXPECT_TRUE(cull_rect.Cutout(flip_lrtb(diff_rect)).has_value()) << label;
2855  EXPECT_EQ(cull_rect.Cutout(flip_lrtb(diff_rect)), cull_rect) << label;
2856 
2857  // flipped(empty) cull_rect vs flipped(empty) diff_rect
2858  // == empty
2859  EXPECT_FALSE(flip_lr(cull_rect).Cutout(diff_rect).has_value()) << label;
2860  EXPECT_EQ(flip_lr(cull_rect).CutoutOrEmpty(diff_rect), IRect()) << label;
2861  EXPECT_FALSE(flip_tb(cull_rect).Cutout(diff_rect).has_value()) << label;
2862  EXPECT_EQ(flip_tb(cull_rect).CutoutOrEmpty(diff_rect), IRect()) << label;
2863  EXPECT_FALSE(flip_lrtb(cull_rect).Cutout(diff_rect).has_value()) << label;
2864  EXPECT_EQ(flip_lrtb(cull_rect).CutoutOrEmpty(diff_rect), IRect()) << label;
2865 
2866  // flipped(empty) cull_rect vs unflipped diff_rect
2867  // == empty
2868  EXPECT_FALSE(flip_lr(cull_rect).Cutout(flip_lr(diff_rect)).has_value())
2869  << label;
2870  EXPECT_EQ(flip_lr(cull_rect).CutoutOrEmpty(flip_lr(diff_rect)), IRect())
2871  << label;
2872  EXPECT_FALSE(flip_tb(cull_rect).Cutout(flip_tb(diff_rect)).has_value())
2873  << label;
2874  EXPECT_EQ(flip_tb(cull_rect).CutoutOrEmpty(flip_tb(diff_rect)), IRect())
2875  << label;
2876  EXPECT_FALSE(flip_lrtb(cull_rect).Cutout(flip_lrtb(diff_rect)).has_value())
2877  << label;
2878  EXPECT_EQ(flip_lrtb(cull_rect).CutoutOrEmpty(flip_lrtb(diff_rect)), IRect())
2879  << label;
2880  };
2881 
2882  auto non_reducing = [&cull_rect, &check_empty_flips](
2883  const IRect& diff_rect, const std::string& label) {
2884  EXPECT_EQ(cull_rect.Cutout(diff_rect), cull_rect) << label;
2885  EXPECT_EQ(cull_rect.CutoutOrEmpty(diff_rect), cull_rect) << label;
2886  check_empty_flips(diff_rect, label);
2887  };
2888 
2889  auto reducing = [&cull_rect, &check_empty_flips](const IRect& diff_rect,
2890  const IRect& result_rect,
2891  const std::string& label) {
2892  EXPECT_TRUE(!result_rect.IsEmpty());
2893  EXPECT_EQ(cull_rect.Cutout(diff_rect), result_rect) << label;
2894  EXPECT_EQ(cull_rect.CutoutOrEmpty(diff_rect), result_rect) << label;
2895  check_empty_flips(diff_rect, label);
2896  };
2897 
2898  auto emptying = [&cull_rect, &check_empty_flips](const IRect& diff_rect,
2899  const std::string& label) {
2900  EXPECT_FALSE(cull_rect.Cutout(diff_rect).has_value()) << label;
2901  EXPECT_EQ(cull_rect.CutoutOrEmpty(diff_rect), IRect()) << label;
2902  check_empty_flips(diff_rect, label);
2903  };
2904 
2905  // Skim the corners and edge
2906  non_reducing(IRect::MakeLTRB(10, 10, 20, 20), "outside UL corner");
2907  non_reducing(IRect::MakeLTRB(20, 10, 40, 20), "Above");
2908  non_reducing(IRect::MakeLTRB(40, 10, 50, 20), "outside UR corner");
2909  non_reducing(IRect::MakeLTRB(40, 20, 50, 40), "Right");
2910  non_reducing(IRect::MakeLTRB(40, 40, 50, 50), "outside LR corner");
2911  non_reducing(IRect::MakeLTRB(20, 40, 40, 50), "Below");
2912  non_reducing(IRect::MakeLTRB(10, 40, 20, 50), "outside LR corner");
2913  non_reducing(IRect::MakeLTRB(10, 20, 20, 40), "Left");
2914 
2915  // Overlap corners
2916  non_reducing(IRect::MakeLTRB(15, 15, 25, 25), "covering UL corner");
2917  non_reducing(IRect::MakeLTRB(35, 15, 45, 25), "covering UR corner");
2918  non_reducing(IRect::MakeLTRB(35, 35, 45, 45), "covering LR corner");
2919  non_reducing(IRect::MakeLTRB(15, 35, 25, 45), "covering LL corner");
2920 
2921  // Overlap edges, but not across an entire side
2922  non_reducing(IRect::MakeLTRB(20, 15, 39, 25), "Top edge left-biased");
2923  non_reducing(IRect::MakeLTRB(21, 15, 40, 25), "Top edge, right biased");
2924  non_reducing(IRect::MakeLTRB(35, 20, 45, 39), "Right edge, top-biased");
2925  non_reducing(IRect::MakeLTRB(35, 21, 45, 40), "Right edge, bottom-biased");
2926  non_reducing(IRect::MakeLTRB(20, 35, 39, 45), "Bottom edge, left-biased");
2927  non_reducing(IRect::MakeLTRB(21, 35, 40, 45), "Bottom edge, right-biased");
2928  non_reducing(IRect::MakeLTRB(15, 20, 25, 39), "Left edge, top-biased");
2929  non_reducing(IRect::MakeLTRB(15, 21, 25, 40), "Left edge, bottom-biased");
2930 
2931  // Slice all the way through the middle
2932  non_reducing(IRect::MakeLTRB(25, 15, 35, 45), "Vertical interior slice");
2933  non_reducing(IRect::MakeLTRB(15, 25, 45, 35), "Horizontal interior slice");
2934 
2935  // Slice off each edge
2936  reducing(IRect::MakeLTRB(20, 15, 40, 25), //
2937  IRect::MakeLTRB(20, 25, 40, 40), //
2938  "Slice off top");
2939  reducing(IRect::MakeLTRB(35, 20, 45, 40), //
2940  IRect::MakeLTRB(20, 20, 35, 40), //
2941  "Slice off right");
2942  reducing(IRect::MakeLTRB(20, 35, 40, 45), //
2943  IRect::MakeLTRB(20, 20, 40, 35), //
2944  "Slice off bottom");
2945  reducing(IRect::MakeLTRB(15, 20, 25, 40), //
2946  IRect::MakeLTRB(25, 20, 40, 40), //
2947  "Slice off left");
2948 
2949  // cull rect contains diff rect
2950  non_reducing(IRect::MakeLTRB(21, 21, 39, 39), "Contained, non-covering");
2951 
2952  // cull rect equals diff rect
2953  emptying(cull_rect, "Perfectly covering");
2954 
2955  // diff rect contains cull rect
2956  emptying(IRect::MakeLTRB(15, 15, 45, 45), "Smothering");
2957 }

References impeller::TRect< T >::Cutout(), impeller::TRect< T >::CutoutOrEmpty(), flip_lr(), flip_lrtb(), flip_tb(), impeller::TRect< T >::IsEmpty(), and impeller::TRect< T >::MakeLTRB().

◆ TEST() [270/465]

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

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

Definition at line 839 of file rect_unittests.cc.

839  {
840  IRect rect = IRect::MakeLTRB(50, 50, 100, 100);
841 
842  auto test = [&rect](int64_t l, int64_t t, int64_t r, int64_t b,
843  const std::string& label) {
844  EXPECT_FALSE(rect.IntersectsWithRect(IRect::MakeLTRB(l, b, r, t)))
845  << label << " with Top/Bottom swapped";
846  EXPECT_FALSE(rect.IntersectsWithRect(IRect::MakeLTRB(r, b, l, t)))
847  << label << " with Left/Right swapped";
848  EXPECT_FALSE(rect.IntersectsWithRect(IRect::MakeLTRB(r, t, l, b)))
849  << label << " with all sides swapped";
850  };
851 
852  test(20, 20, 30, 30, "Above and Left");
853  test(70, 20, 80, 30, "Above");
854  test(120, 20, 130, 30, "Above and Right");
855  test(120, 70, 130, 80, "Right");
856  test(120, 120, 130, 130, "Below and Right");
857  test(70, 120, 80, 130, "Below");
858  test(20, 120, 30, 130, "Below and Left");
859  test(20, 70, 30, 80, "Left");
860 
861  test(70, 70, 80, 80, "Inside");
862 
863  test(40, 70, 60, 80, "Straddling Left");
864  test(70, 40, 80, 60, "Straddling Top");
865  test(90, 70, 110, 80, "Straddling Right");
866  test(70, 90, 80, 110, "Straddling Bottom");
867 }

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

◆ TEST() [272/465]

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

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

Definition at line 1283 of file rect_unittests.cc.

1283  {
1284  auto rect = IRect::MakeLTRB(100, 100, 200, 200);
1285 
1286  // Expand(T amount)
1287  EXPECT_EQ(rect.Expand(10), IRect::MakeLTRB(90, 90, 210, 210));
1288  EXPECT_EQ(rect.Expand(-10), IRect::MakeLTRB(110, 110, 190, 190));
1289 
1290  // Expand(amount, amount)
1291  EXPECT_EQ(rect.Expand(10, 10), IRect::MakeLTRB(90, 90, 210, 210));
1292  EXPECT_EQ(rect.Expand(10, -10), IRect::MakeLTRB(90, 110, 210, 190));
1293  EXPECT_EQ(rect.Expand(-10, 10), IRect::MakeLTRB(110, 90, 190, 210));
1294  EXPECT_EQ(rect.Expand(-10, -10), IRect::MakeLTRB(110, 110, 190, 190));
1295 
1296  // Expand(amount, amount, amount, amount)
1297  EXPECT_EQ(rect.Expand(10, 20, 30, 40), IRect::MakeLTRB(90, 80, 230, 240));
1298  EXPECT_EQ(rect.Expand(-10, 20, 30, 40), IRect::MakeLTRB(110, 80, 230, 240));
1299  EXPECT_EQ(rect.Expand(10, -20, 30, 40), IRect::MakeLTRB(90, 120, 230, 240));
1300  EXPECT_EQ(rect.Expand(10, 20, -30, 40), IRect::MakeLTRB(90, 80, 170, 240));
1301  EXPECT_EQ(rect.Expand(10, 20, 30, -40), IRect::MakeLTRB(90, 80, 230, 160));
1302 
1303  // Expand(IPoint amount)
1304  EXPECT_EQ(rect.Expand(IPoint{10, 10}), IRect::MakeLTRB(90, 90, 210, 210));
1305  EXPECT_EQ(rect.Expand(IPoint{10, -10}), IRect::MakeLTRB(90, 110, 210, 190));
1306  EXPECT_EQ(rect.Expand(IPoint{-10, 10}), IRect::MakeLTRB(110, 90, 190, 210));
1307  EXPECT_EQ(rect.Expand(IPoint{-10, -10}), IRect::MakeLTRB(110, 110, 190, 190));
1308 
1309  // Expand(ISize amount)
1310  EXPECT_EQ(rect.Expand(ISize{10, 10}), IRect::MakeLTRB(90, 90, 210, 210));
1311  EXPECT_EQ(rect.Expand(ISize{10, -10}), IRect::MakeLTRB(90, 110, 210, 190));
1312  EXPECT_EQ(rect.Expand(ISize{-10, 10}), IRect::MakeLTRB(110, 90, 190, 210));
1313  EXPECT_EQ(rect.Expand(ISize{-10, -10}), IRect::MakeLTRB(110, 110, 190, 190));
1314 }

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

◆ TEST() [274/465]

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

Definition at line 661 of file rect_unittests.cc.

661  {
662  EXPECT_EQ(IRect(IRect::MakeXYWH(2, 3, 7, 15)), //
663  IRect::MakeXYWH(2, 3, 7, 15));
664  EXPECT_EQ(IRect(IRect::MakeLTRB(2, 3, 7, 15)), //
665  IRect::MakeLTRB(2, 3, 7, 15));
666 }

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

◆ TEST() [275/465]

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

Definition at line 1122 of file rect_unittests.cc.

1122  {
1123  {
1124  // Checks for expected matrix values
1125 
1126  auto r = IRect::MakeXYWH(100, 200, 200, 400);
1127 
1128  EXPECT_EQ(r.GetNormalizingTransform(),
1129  Matrix::MakeScale({0.005, 0.0025, 1.0}) *
1130  Matrix::MakeTranslation({-100, -200}));
1131  }
1132 
1133  {
1134  // Checks for expected transform of points relative to the rect
1135 
1136  auto r = IRect::MakeLTRB(300, 500, 400, 700);
1137  auto m = r.GetNormalizingTransform();
1138 
1139  // The 4 corners of the rect => (0, 0) to (1, 1)
1140  EXPECT_EQ(m * Point(300, 500), Point(0, 0));
1141  EXPECT_EQ(m * Point(400, 500), Point(1, 0));
1142  EXPECT_EQ(m * Point(400, 700), Point(1, 1));
1143  EXPECT_EQ(m * Point(300, 700), Point(0, 1));
1144 
1145  // The center => (0.5, 0.5)
1146  EXPECT_EQ(m * Point(350, 600), Point(0.5, 0.5));
1147 
1148  // Outside the 4 corners => (-1, -1) to (2, 2)
1149  EXPECT_EQ(m * Point(200, 300), Point(-1, -1));
1150  EXPECT_EQ(m * Point(500, 300), Point(2, -1));
1151  EXPECT_EQ(m * Point(500, 900), Point(2, 2));
1152  EXPECT_EQ(m * Point(200, 900), Point(-1, 2));
1153  }
1154 
1155  {
1156  // Checks for behavior with empty rects
1157 
1158  auto zero = Matrix::MakeScale({0.0, 0.0, 1.0});
1159 
1160  // Empty for width and/or height == 0
1161  EXPECT_EQ(IRect::MakeXYWH(10, 10, 0, 10).GetNormalizingTransform(), zero);
1162  EXPECT_EQ(IRect::MakeXYWH(10, 10, 10, 0).GetNormalizingTransform(), zero);
1163  EXPECT_EQ(IRect::MakeXYWH(10, 10, 0, 0).GetNormalizingTransform(), zero);
1164 
1165  // Empty for width and/or height < 0
1166  EXPECT_EQ(IRect::MakeXYWH(10, 10, -1, 10).GetNormalizingTransform(), zero);
1167  EXPECT_EQ(IRect::MakeXYWH(10, 10, 10, -1).GetNormalizingTransform(), zero);
1168  EXPECT_EQ(IRect::MakeXYWH(10, 10, -1, -1).GetNormalizingTransform(), zero);
1169  }
1170 }

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

◆ TEST() [276/465]

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

Definition at line 1800 of file rect_unittests.cc.

1800  {
1801  auto check_empty_flips = [](const IRect& a, const IRect& b,
1802  const std::string& label) {
1803  ASSERT_FALSE(a.IsEmpty());
1804  // b is allowed to be empty
1805 
1806  // unflipped a vs flipped (empty) b yields a
1807  EXPECT_FALSE(a.Intersection(flip_lr(b)).has_value()) << label;
1808  EXPECT_FALSE(a.Intersection(flip_tb(b)).has_value()) << label;
1809  EXPECT_FALSE(a.Intersection(flip_lrtb(b)).has_value()) << label;
1810 
1811  // flipped (empty) a vs unflipped b yields b
1812  EXPECT_FALSE(flip_lr(a).Intersection(b).has_value()) << label;
1813  EXPECT_FALSE(flip_tb(a).Intersection(b).has_value()) << label;
1814  EXPECT_FALSE(flip_lrtb(a).Intersection(b).has_value()) << label;
1815 
1816  // flipped (empty) a vs flipped (empty) b yields empty
1817  EXPECT_FALSE(flip_lr(a).Intersection(flip_lr(b)).has_value()) << label;
1818  EXPECT_FALSE(flip_tb(a).Intersection(flip_tb(b)).has_value()) << label;
1819  EXPECT_FALSE(flip_lrtb(a).Intersection(flip_lrtb(b)).has_value()) << label;
1820  };
1821 
1822  auto test_non_empty = [&check_empty_flips](const IRect& a, const IRect& b,
1823  const IRect& result) {
1824  ASSERT_FALSE(a.IsEmpty()) << a;
1825  // b is allowed to be empty
1826 
1827  std::stringstream stream;
1828  stream << a << " union " << b;
1829  auto label = stream.str();
1830 
1831  EXPECT_TRUE(a.Intersection(b).has_value()) << label;
1832  EXPECT_TRUE(b.Intersection(a).has_value()) << label;
1833  EXPECT_EQ(a.Intersection(b), result) << label;
1834  EXPECT_EQ(b.Intersection(a), result) << label;
1835  check_empty_flips(a, b, label);
1836  };
1837 
1838  auto test_empty = [&check_empty_flips](const IRect& a, const IRect& b) {
1839  ASSERT_FALSE(a.IsEmpty()) << a;
1840  // b is allowed to be empty
1841 
1842  std::stringstream stream;
1843  stream << a << " union " << b;
1844  auto label = stream.str();
1845 
1846  EXPECT_FALSE(a.Intersection(b).has_value()) << label;
1847  EXPECT_FALSE(b.Intersection(a).has_value()) << label;
1848  check_empty_flips(a, b, label);
1849  };
1850 
1851  {
1852  auto a = IRect::MakeXYWH(100, 100, 100, 100);
1853  auto b = IRect::MakeXYWH(0, 0, 0, 0);
1854 
1855  test_empty(a, b);
1856  }
1857 
1858  {
1859  auto a = IRect::MakeXYWH(100, 100, 100, 100);
1860  auto b = IRect::MakeXYWH(10, 10, 0, 0);
1861 
1862  test_empty(a, b);
1863  }
1864 
1865  {
1866  auto a = IRect::MakeXYWH(0, 0, 100, 100);
1867  auto b = IRect::MakeXYWH(10, 10, 100, 100);
1868  auto expected = IRect::MakeXYWH(10, 10, 90, 90);
1869 
1870  test_non_empty(a, b, expected);
1871  }
1872 
1873  {
1874  auto a = IRect::MakeXYWH(0, 0, 100, 100);
1875  auto b = IRect::MakeXYWH(100, 100, 100, 100);
1876 
1877  test_empty(a, b);
1878  }
1879 
1880  {
1881  auto a = IRect::MakeMaximum();
1882  auto b = IRect::MakeXYWH(10, 10, 300, 300);
1883 
1884  test_non_empty(a, b, b);
1885  }
1886 
1887  {
1888  auto a = IRect::MakeMaximum();
1889  auto b = IRect::MakeMaximum();
1890 
1891  test_non_empty(a, b, IRect::MakeMaximum());
1892  }
1893 }

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

◆ TEST() [277/465]

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

Definition at line 2065 of file rect_unittests.cc.

2065  {
2066  auto check_empty_flips = [](const IRect& a, const IRect& b,
2067  const std::string& label) {
2068  ASSERT_FALSE(a.IsEmpty());
2069  // b is allowed to be empty
2070 
2071  // unflipped a vs flipped (empty) b yields a
2072  EXPECT_FALSE(a.IntersectsWithRect(flip_lr(b))) << label;
2073  EXPECT_FALSE(a.IntersectsWithRect(flip_tb(b))) << label;
2074  EXPECT_FALSE(a.IntersectsWithRect(flip_lrtb(b))) << label;
2075 
2076  // flipped (empty) a vs unflipped b yields b
2077  EXPECT_FALSE(flip_lr(a).IntersectsWithRect(b)) << label;
2078  EXPECT_FALSE(flip_tb(a).IntersectsWithRect(b)) << label;
2079  EXPECT_FALSE(flip_lrtb(a).IntersectsWithRect(b)) << label;
2080 
2081  // flipped (empty) a vs flipped (empty) b yields empty
2082  EXPECT_FALSE(flip_lr(a).IntersectsWithRect(flip_lr(b))) << label;
2083  EXPECT_FALSE(flip_tb(a).IntersectsWithRect(flip_tb(b))) << label;
2084  EXPECT_FALSE(flip_lrtb(a).IntersectsWithRect(flip_lrtb(b))) << label;
2085  };
2086 
2087  auto test_non_empty = [&check_empty_flips](const IRect& a, const IRect& b) {
2088  ASSERT_FALSE(a.IsEmpty()) << a;
2089  // b is allowed to be empty
2090 
2091  std::stringstream stream;
2092  stream << a << " union " << b;
2093  auto label = stream.str();
2094 
2095  EXPECT_TRUE(a.IntersectsWithRect(b)) << label;
2096  EXPECT_TRUE(b.IntersectsWithRect(a)) << label;
2097  check_empty_flips(a, b, label);
2098  };
2099 
2100  auto test_empty = [&check_empty_flips](const IRect& a, const IRect& b) {
2101  ASSERT_FALSE(a.IsEmpty()) << a;
2102  // b is allowed to be empty
2103 
2104  std::stringstream stream;
2105  stream << a << " union " << b;
2106  auto label = stream.str();
2107 
2108  EXPECT_FALSE(a.IntersectsWithRect(b)) << label;
2109  EXPECT_FALSE(b.IntersectsWithRect(a)) << label;
2110  check_empty_flips(a, b, label);
2111  };
2112 
2113  {
2114  auto a = IRect::MakeXYWH(100, 100, 100, 100);
2115  auto b = IRect::MakeXYWH(0, 0, 0, 0);
2116 
2117  test_empty(a, b);
2118  }
2119 
2120  {
2121  auto a = IRect::MakeXYWH(100, 100, 100, 100);
2122  auto b = IRect::MakeXYWH(10, 10, 0, 0);
2123 
2124  test_empty(a, b);
2125  }
2126 
2127  {
2128  auto a = IRect::MakeXYWH(0, 0, 100, 100);
2129  auto b = IRect::MakeXYWH(10, 10, 100, 100);
2130 
2131  test_non_empty(a, b);
2132  }
2133 
2134  {
2135  auto a = IRect::MakeXYWH(0, 0, 100, 100);
2136  auto b = IRect::MakeXYWH(100, 100, 100, 100);
2137 
2138  test_empty(a, b);
2139  }
2140 
2141  {
2142  auto a = IRect::MakeMaximum();
2143  auto b = IRect::MakeXYWH(10, 10, 100, 100);
2144 
2145  test_non_empty(a, b);
2146  }
2147 
2148  {
2149  auto a = IRect::MakeMaximum();
2150  auto b = IRect::MakeMaximum();
2151 
2152  test_non_empty(a, b);
2153  }
2154 }

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

◆ TEST() [278/465]

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

Definition at line 638 of file rect_unittests.cc.

638  {
639  IRect rect = IRect::MakeMaximum();
640  auto min = std::numeric_limits<int64_t>::min();
641  auto max = std::numeric_limits<int64_t>::max();
642 
643  EXPECT_EQ(rect.GetLeft(), min);
644  EXPECT_EQ(rect.GetTop(), min);
645  EXPECT_EQ(rect.GetRight(), max);
646  EXPECT_EQ(rect.GetBottom(), max);
647  EXPECT_EQ(rect.GetX(), min);
648  EXPECT_EQ(rect.GetY(), min);
649  EXPECT_EQ(rect.GetWidth(), max);
650  EXPECT_EQ(rect.GetHeight(), max);
651  EXPECT_FALSE(rect.IsEmpty());
652 }

References impeller::TRect< T >::GetBottom(), impeller::TRect< T >::GetHeight(), impeller::TRect< T >::GetLeft(), impeller::TRect< T >::GetRight(), impeller::TRect< T >::GetTop(), impeller::TRect< T >::GetWidth(), impeller::TRect< T >::GetX(), impeller::TRect< T >::GetY(), impeller::TRect< T >::IsEmpty(), and impeller::TRect< T >::MakeMaximum().

◆ TEST() [279/465]

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

Definition at line 728 of file rect_unittests.cc.

728  {
729  {
730  IRect r = IRect::MakeOriginSize({10, 20}, {50, 40});
731  EXPECT_EQ(r.GetOrigin(), IPoint(10, 20));
732  EXPECT_EQ(r.GetSize(), ISize(50, 40));
733  EXPECT_EQ(r.GetX(), 10);
734  EXPECT_EQ(r.GetY(), 20);
735  EXPECT_EQ(r.GetWidth(), 50);
736  EXPECT_EQ(r.GetHeight(), 40);
737  auto expected_array = std::array<int64_t, 4>{10, 20, 50, 40};
738  EXPECT_EQ(r.GetXYWH(), expected_array);
739  }
740 
741  {
742  IRect r = IRect::MakeLTRB(10, 20, 50, 40);
743  EXPECT_EQ(r.GetOrigin(), IPoint(10, 20));
744  EXPECT_EQ(r.GetSize(), ISize(40, 20));
745  EXPECT_EQ(r.GetX(), 10);
746  EXPECT_EQ(r.GetY(), 20);
747  EXPECT_EQ(r.GetWidth(), 40);
748  EXPECT_EQ(r.GetHeight(), 20);
749  auto expected_array = std::array<int64_t, 4>{10, 20, 40, 20};
750  EXPECT_EQ(r.GetXYWH(), expected_array);
751  }
752 }

References impeller::TRect< T >::GetHeight(), impeller::TRect< T >::GetOrigin(), impeller::TRect< T >::GetSize(), impeller::TRect< T >::GetWidth(), impeller::TRect< T >::GetX(), impeller::TRect< T >::GetXYWH(), impeller::TRect< T >::GetY(), impeller::TRect< T >::MakeLTRB(), and impeller::TRect< T >::MakeOriginSize().

◆ TEST() [280/465]

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

Definition at line 523 of file rect_unittests.cc.

523  {
524  auto min = std::numeric_limits<int64_t>::min();
525  auto max = std::numeric_limits<int64_t>::max();
526 
527  // 4 cases
528  // negative l, r near max takes width past max
529  // positive l, r near min takes width below min
530  // negative t, b near max takes width past max
531  // positive t, b near min takes width below min
532 
533  {
534  IRect rect = IRect::MakeLTRB(-10, 10, max - 5, 26);
535 
536  EXPECT_EQ(rect.GetLeft(), -10);
537  EXPECT_EQ(rect.GetTop(), 10);
538  EXPECT_EQ(rect.GetRight(), max - 5);
539  EXPECT_EQ(rect.GetBottom(), 26);
540  EXPECT_EQ(rect.GetX(), -10);
541  EXPECT_EQ(rect.GetY(), 10);
542  EXPECT_EQ(rect.GetWidth(), max);
543  EXPECT_EQ(rect.GetHeight(), 16);
544  EXPECT_FALSE(rect.IsEmpty());
545  }
546 
547  {
548  IRect rect = IRect::MakeLTRB(10, 10, min + 5, 26);
549 
550  EXPECT_EQ(rect.GetLeft(), 10);
551  EXPECT_EQ(rect.GetTop(), 10);
552  EXPECT_EQ(rect.GetRight(), min + 5);
553  EXPECT_EQ(rect.GetBottom(), 26);
554  EXPECT_EQ(rect.GetX(), 10);
555  EXPECT_EQ(rect.GetY(), 10);
556  EXPECT_EQ(rect.GetWidth(), min);
557  EXPECT_EQ(rect.GetHeight(), 16);
558  EXPECT_TRUE(rect.IsEmpty());
559  }
560 
561  {
562  IRect rect = IRect::MakeLTRB(5, -10, 15, max - 5);
563 
564  EXPECT_EQ(rect.GetLeft(), 5);
565  EXPECT_EQ(rect.GetTop(), -10);
566  EXPECT_EQ(rect.GetRight(), 15);
567  EXPECT_EQ(rect.GetBottom(), max - 5);
568  EXPECT_EQ(rect.GetX(), 5);
569  EXPECT_EQ(rect.GetY(), -10);
570  EXPECT_EQ(rect.GetWidth(), 10);
571  EXPECT_EQ(rect.GetHeight(), max);
572  EXPECT_FALSE(rect.IsEmpty());
573  }
574 
575  {
576  IRect rect = IRect::MakeLTRB(5, 10, 15, min + 5);
577 
578  EXPECT_EQ(rect.GetLeft(), 5);
579  EXPECT_EQ(rect.GetTop(), 10);
580  EXPECT_EQ(rect.GetRight(), 15);
581  EXPECT_EQ(rect.GetBottom(), min + 5);
582  EXPECT_EQ(rect.GetX(), 5);
583  EXPECT_EQ(rect.GetY(), 10);
584  EXPECT_EQ(rect.GetWidth(), 10);
585  EXPECT_EQ(rect.GetHeight(), min);
586  EXPECT_TRUE(rect.IsEmpty());
587  }
588 }

References impeller::TRect< T >::GetBottom(), impeller::TRect< T >::GetHeight(), impeller::TRect< T >::GetLeft(), impeller::TRect< T >::GetRight(), impeller::TRect< T >::GetTop(), impeller::TRect< T >::GetWidth(), impeller::TRect< T >::GetX(), impeller::TRect< T >::GetY(), impeller::TRect< T >::IsEmpty(), and impeller::TRect< T >::MakeLTRB().

◆ TEST() [281/465]

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

Definition at line 317 of file rect_unittests.cc.

317  {
318  auto min = std::numeric_limits<int64_t>::min();
319  auto max = std::numeric_limits<int64_t>::max();
320 
321  // 4 cases
322  // x near max, positive w takes it past max
323  // x near min, negative w takes it below min
324  // y near max, positive h takes it past max
325  // y near min, negative h takes it below min
326 
327  {
328  IRect rect = IRect::MakeXYWH(max - 5, 10, 10, 16);
329 
330  EXPECT_EQ(rect.GetLeft(), max - 5);
331  EXPECT_EQ(rect.GetTop(), 10);
332  EXPECT_EQ(rect.GetRight(), max);
333  EXPECT_EQ(rect.GetBottom(), 26);
334  EXPECT_EQ(rect.GetX(), max - 5);
335  EXPECT_EQ(rect.GetY(), 10);
336  EXPECT_EQ(rect.GetWidth(), 5);
337  EXPECT_EQ(rect.GetHeight(), 16);
338  EXPECT_FALSE(rect.IsEmpty());
339  }
340 
341  {
342  IRect rect = IRect::MakeXYWH(min + 5, 10, -10, 16);
343 
344  EXPECT_EQ(rect.GetLeft(), min + 5);
345  EXPECT_EQ(rect.GetTop(), 10);
346  EXPECT_EQ(rect.GetRight(), min);
347  EXPECT_EQ(rect.GetBottom(), 26);
348  EXPECT_EQ(rect.GetX(), min + 5);
349  EXPECT_EQ(rect.GetY(), 10);
350  EXPECT_EQ(rect.GetWidth(), -5);
351  EXPECT_EQ(rect.GetHeight(), 16);
352  EXPECT_TRUE(rect.IsEmpty());
353  }
354 
355  {
356  IRect rect = IRect::MakeXYWH(5, max - 10, 10, 16);
357 
358  EXPECT_EQ(rect.GetLeft(), 5);
359  EXPECT_EQ(rect.GetTop(), max - 10);
360  EXPECT_EQ(rect.GetRight(), 15);
361  EXPECT_EQ(rect.GetBottom(), max);
362  EXPECT_EQ(rect.GetX(), 5);
363  EXPECT_EQ(rect.GetY(), max - 10);
364  EXPECT_EQ(rect.GetWidth(), 10);
365  EXPECT_EQ(rect.GetHeight(), 10);
366  EXPECT_FALSE(rect.IsEmpty());
367  }
368 
369  {
370  IRect rect = IRect::MakeXYWH(5, min + 10, 10, -16);
371 
372  EXPECT_EQ(rect.GetLeft(), 5);
373  EXPECT_EQ(rect.GetTop(), min + 10);
374  EXPECT_EQ(rect.GetRight(), 15);
375  EXPECT_EQ(rect.GetBottom(), min);
376  EXPECT_EQ(rect.GetX(), 5);
377  EXPECT_EQ(rect.GetY(), min + 10);
378  EXPECT_EQ(rect.GetWidth(), 10);
379  EXPECT_EQ(rect.GetHeight(), -10);
380  EXPECT_TRUE(rect.IsEmpty());
381  }
382 }

References impeller::TRect< T >::GetBottom(), impeller::TRect< T >::GetHeight(), impeller::TRect< T >::GetLeft(), impeller::TRect< T >::GetRight(), impeller::TRect< T >::GetTop(), impeller::TRect< T >::GetWidth(), impeller::TRect< T >::GetX(), impeller::TRect< T >::GetY(), impeller::TRect< T >::IsEmpty(), and impeller::TRect< T >::MakeXYWH().

◆ TEST() [282/465]

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

Definition at line 3098 of file rect_unittests.cc.

3098  {
3099  {
3100  auto r = Rect::MakeLTRB(-100, -200, 300, 400);
3101  auto ir = IRect::MakeLTRB(-100, -200, 300, 400);
3102  EXPECT_EQ(IRect::Round(r), ir);
3103  }
3104  {
3105  auto r = Rect::MakeLTRB(-100.4, -200.4, 300.4, 400.4);
3106  auto ir = IRect::MakeLTRB(-100, -200, 300, 400);
3107  EXPECT_EQ(IRect::Round(r), ir);
3108  }
3109  {
3110  auto r = Rect::MakeLTRB(-100.5, -200.5, 300.5, 400.5);
3111  auto ir = IRect::MakeLTRB(-101, -201, 301, 401);
3112  EXPECT_EQ(IRect::Round(r), ir);
3113  }
3114 }

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

◆ TEST() [283/465]

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

Definition at line 3070 of file rect_unittests.cc.

3070  {
3071  {
3072  auto r = Rect::MakeLTRB(-100, -200, 300, 400);
3073  auto ir = IRect::MakeLTRB(-100, -200, 300, 400);
3074  EXPECT_EQ(IRect::RoundOut(r), ir);
3075  }
3076  {
3077  auto r = Rect::MakeLTRB(-100.1, -200.1, 300.1, 400.1);
3078  auto ir = IRect::MakeLTRB(-101, -201, 301, 401);
3079  EXPECT_EQ(IRect::RoundOut(r), ir);
3080  }
3081 }

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

◆ TEST() [284/465]

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

Definition at line 974 of file rect_unittests.cc.

974  {
975  auto test1 = [](IRect rect, int64_t scale) {
976  IRect expected = IRect::MakeXYWH(rect.GetX() * scale, //
977  rect.GetY() * scale, //
978  rect.GetWidth() * scale, //
979  rect.GetHeight() * scale);
980 
981  EXPECT_EQ(rect.Scale(scale), expected) //
982  << rect << " * " << scale;
983  EXPECT_EQ(rect.Scale(scale, scale), expected) //
984  << rect << " * " << scale;
985  EXPECT_EQ(rect.Scale(IPoint(scale, scale)), expected) //
986  << rect << " * " << scale;
987  EXPECT_EQ(rect.Scale(ISize(scale, scale)), expected) //
988  << rect << " * " << scale;
989  };
990 
991  auto test2 = [&test1](IRect rect, int64_t scale_x, int64_t scale_y) {
992  IRect expected = IRect::MakeXYWH(rect.GetX() * scale_x, //
993  rect.GetY() * scale_y, //
994  rect.GetWidth() * scale_x, //
995  rect.GetHeight() * scale_y);
996 
997  EXPECT_EQ(rect.Scale(scale_x, scale_y), expected) //
998  << rect << " * " << scale_x << ", " << scale_y;
999  EXPECT_EQ(rect.Scale(IPoint(scale_x, scale_y)), expected) //
1000  << rect << " * " << scale_x << ", " << scale_y;
1001  EXPECT_EQ(rect.Scale(ISize(scale_x, scale_y)), expected) //
1002  << rect << " * " << scale_x << ", " << scale_y;
1003 
1004  test1(rect, scale_x);
1005  test1(rect, scale_y);
1006  };
1007 
1008  test2(IRect::MakeLTRB(10, 15, 100, 150), 2, 3);
1009  test2(IRect::MakeLTRB(10, 15, 100, 150), 3, 2);
1010  test2(IRect::MakeLTRB(10, 15, -100, 150), 2, 3);
1011  test2(IRect::MakeLTRB(10, 15, 100, -150), 2, 3);
1012  test2(IRect::MakeLTRB(10, 15, 100, 150), -2, 3);
1013  test2(IRect::MakeLTRB(10, 15, 100, 150), 2, -3);
1014 }

References impeller::TRect< T >::GetHeight(), impeller::TRect< T >::GetWidth(), impeller::TRect< T >::GetX(), impeller::TRect< T >::GetY(), impeller::TRect< T >::MakeLTRB(), impeller::TRect< T >::MakeXYWH(), scale, and impeller::TRect< T >::Scale().

◆ TEST() [285/465]

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

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

Definition at line 149 of file rect_unittests.cc.

149  {
150  // Using fractional-power-of-2 friendly values for equality tests
151  IRect rect = IRect::MakeWH(15, 25);
152 
153  EXPECT_EQ(rect.GetLeft(), 0);
154  EXPECT_EQ(rect.GetTop(), 0);
155  EXPECT_EQ(rect.GetRight(), 15);
156  EXPECT_EQ(rect.GetBottom(), 25);
157  EXPECT_EQ(rect.GetX(), 0);
158  EXPECT_EQ(rect.GetY(), 0);
159  EXPECT_EQ(rect.GetWidth(), 15);
160  EXPECT_EQ(rect.GetHeight(), 25);
161  EXPECT_FALSE(rect.IsEmpty());
162 }

References impeller::TRect< T >::GetBottom(), impeller::TRect< T >::GetHeight(), impeller::TRect< T >::GetLeft(), impeller::TRect< T >::GetRight(), impeller::TRect< T >::GetTop(), impeller::TRect< T >::GetWidth(), impeller::TRect< T >::GetX(), impeller::TRect< T >::GetY(), impeller::TRect< T >::IsEmpty(), and impeller::TRect< T >::MakeWH().

◆ TEST() [287/465]

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

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

Definition at line 1497 of file rect_unittests.cc.

1497  {
1498  auto check_empty_flips = [](const IRect& a, const IRect& b,
1499  const std::string& label) {
1500  ASSERT_FALSE(a.IsEmpty());
1501  // b is allowed to be empty
1502 
1503  // unflipped a vs flipped (empty) b yields a
1504  EXPECT_EQ(a.Union(flip_lr(b)), a) << label;
1505  EXPECT_EQ(a.Union(flip_tb(b)), a) << label;
1506  EXPECT_EQ(a.Union(flip_lrtb(b)), a) << label;
1507 
1508  // flipped (empty) a vs unflipped b yields b
1509  EXPECT_EQ(flip_lr(a).Union(b), b) << label;
1510  EXPECT_EQ(flip_tb(a).Union(b), b) << label;
1511  EXPECT_EQ(flip_lrtb(a).Union(b), b) << label;
1512 
1513  // flipped (empty) a vs flipped (empty) b yields empty
1514  EXPECT_TRUE(flip_lr(a).Union(flip_lr(b)).IsEmpty()) << label;
1515  EXPECT_TRUE(flip_tb(a).Union(flip_tb(b)).IsEmpty()) << label;
1516  EXPECT_TRUE(flip_lrtb(a).Union(flip_lrtb(b)).IsEmpty()) << label;
1517  };
1518 
1519  auto test = [&check_empty_flips](const IRect& a, const IRect& b,
1520  const IRect& result) {
1521  ASSERT_FALSE(a.IsEmpty()) << a;
1522  // b is allowed to be empty
1523 
1524  std::stringstream stream;
1525  stream << a << " union " << b;
1526  auto label = stream.str();
1527 
1528  EXPECT_EQ(a.Union(b), result) << label;
1529  EXPECT_EQ(b.Union(a), result) << label;
1530  check_empty_flips(a, b, label);
1531  };
1532 
1533  {
1534  auto a = IRect::MakeXYWH(100, 100, 100, 100);
1535  auto b = IRect::MakeXYWH(0, 0, 0, 0);
1536  auto expected = IRect::MakeXYWH(100, 100, 100, 100);
1537  test(a, b, expected);
1538  }
1539 
1540  {
1541  auto a = IRect::MakeXYWH(100, 100, 100, 100);
1542  auto b = IRect::MakeXYWH(0, 0, 1, 1);
1543  auto expected = IRect::MakeXYWH(0, 0, 200, 200);
1544  test(a, b, expected);
1545  }
1546 
1547  {
1548  auto a = IRect::MakeXYWH(100, 100, 100, 100);
1549  auto b = IRect::MakeXYWH(10, 10, 1, 1);
1550  auto expected = IRect::MakeXYWH(10, 10, 190, 190);
1551  test(a, b, expected);
1552  }
1553 
1554  {
1555  auto a = IRect::MakeXYWH(0, 0, 100, 100);
1556  auto b = IRect::MakeXYWH(10, 10, 100, 100);
1557  auto expected = IRect::MakeXYWH(0, 0, 110, 110);
1558  test(a, b, expected);
1559  }
1560 
1561  {
1562  auto a = IRect::MakeXYWH(0, 0, 100, 100);
1563  auto b = IRect::MakeXYWH(100, 100, 100, 100);
1564  auto expected = IRect::MakeXYWH(0, 0, 200, 200);
1565  test(a, b, expected);
1566  }
1567 }

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

◆ TEST() [289/465]

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

Definition at line 1196 of file rect_unittests.cc.

1196  {
1197  // Non-empty
1198  EXPECT_FALSE(IRect::MakeXYWH(1, 2, 10, 7).IsEmpty());
1199 
1200  // Empty both width and height both 0 or negative, in all combinations
1201  EXPECT_TRUE(IRect::MakeXYWH(1, 2, 0, 0).IsEmpty());
1202  EXPECT_TRUE(IRect::MakeXYWH(1, 2, -1, -1).IsEmpty());
1203  EXPECT_TRUE(IRect::MakeXYWH(1, 2, -1, 0).IsEmpty());
1204  EXPECT_TRUE(IRect::MakeXYWH(1, 2, 0, -1).IsEmpty());
1205 
1206  // Empty for 0 or negative width or height (but not both at the same time)
1207  EXPECT_TRUE(IRect::MakeXYWH(1, 2, 10, 0).IsEmpty());
1208  EXPECT_TRUE(IRect::MakeXYWH(1, 2, 10, -1).IsEmpty());
1209  EXPECT_TRUE(IRect::MakeXYWH(1, 2, 0, 7).IsEmpty());
1210  EXPECT_TRUE(IRect::MakeXYWH(1, 2, -1, 7).IsEmpty());
1211 }

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

◆ TEST() [290/465]

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

Definition at line 1227 of file rect_unittests.cc.

1227  {
1228  EXPECT_TRUE(Rect::MakeXYWH(10, 30, 20, 20).IsSquare());
1229  EXPECT_FALSE(Rect::MakeXYWH(10, 30, 20, 19).IsSquare());
1230  EXPECT_FALSE(Rect::MakeXYWH(10, 30, 19, 20).IsSquare());
1231  EXPECT_TRUE(Rect::MakeMaximum().IsSquare());
1232 
1233  EXPECT_TRUE(IRect::MakeXYWH(10, 30, 20, 20).IsSquare());
1234  EXPECT_FALSE(IRect::MakeXYWH(10, 30, 20, 19).IsSquare());
1235  EXPECT_FALSE(IRect::MakeXYWH(10, 30, 19, 20).IsSquare());
1236  EXPECT_TRUE(IRect::MakeMaximum().IsSquare());
1237 }

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

◆ TEST() [291/465]

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

Definition at line 1213 of file rect_unittests.cc.

1213  {
1214  Quad quad = {
1215  Point(10, 10),
1216  Point(20, 10),
1217  Point(10, 20),
1218  Point(20, 20),
1219  };
1220  std::optional<Rect> bounds = Rect::MakePointBounds(quad);
1221  EXPECT_TRUE(bounds.has_value());
1222  if (bounds.has_value()) {
1223  EXPECT_TRUE(RectNear(bounds.value(), Rect::MakeLTRB(10, 10, 20, 20)));
1224  }
1225 }
inline ::testing::AssertionResult RectNear(impeller::Rect a, impeller::Rect b)
std::array< Point, 4 > Quad
Definition: point.h:332

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

◆ TEST() [292/465]

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

Definition at line 1895 of file rect_unittests.cc.

1895  {
1896  auto a = IRect::MakeLTRB(0, 0, 110, 110);
1897  auto b = IRect::MakeLTRB(100, 100, 200, 200);
1898  auto c = IRect::MakeLTRB(100, 0, 200, 110);
1899 
1900  // NullOpt, NullOpt
1901  EXPECT_FALSE(IRect::Intersection(std::nullopt, std::nullopt).has_value());
1902  EXPECT_EQ(IRect::Intersection(std::nullopt, std::nullopt), std::nullopt);
1903 
1904  auto test1 = [](const IRect& r) {
1905  // Rect, NullOpt
1906  EXPECT_TRUE(IRect::Intersection(r, std::nullopt).has_value());
1907  EXPECT_EQ(IRect::Intersection(r, std::nullopt).value(), r);
1908 
1909  // OptRect, NullOpt
1910  EXPECT_TRUE(
1911  IRect::Intersection(std::optional(r), std::nullopt).has_value());
1912  EXPECT_EQ(IRect::Intersection(std::optional(r), std::nullopt).value(), r);
1913 
1914  // NullOpt, Rect
1915  EXPECT_TRUE(IRect::Intersection(std::nullopt, r).has_value());
1916  EXPECT_EQ(IRect::Intersection(std::nullopt, r).value(), r);
1917 
1918  // NullOpt, OptRect
1919  EXPECT_TRUE(
1920  IRect::Intersection(std::nullopt, std::optional(r)).has_value());
1921  EXPECT_EQ(IRect::Intersection(std::nullopt, std::optional(r)).value(), r);
1922  };
1923 
1924  test1(a);
1925  test1(b);
1926  test1(c);
1927 
1928  auto test2 = [](const IRect& a, const IRect& b, const IRect& i) {
1929  ASSERT_EQ(a.Intersection(b), i);
1930 
1931  // Rect, OptRect
1932  EXPECT_TRUE(IRect::Intersection(a, std::optional(b)).has_value());
1933  EXPECT_EQ(IRect::Intersection(a, std::optional(b)).value(), i);
1934 
1935  // OptRect, Rect
1936  EXPECT_TRUE(IRect::Intersection(std::optional(a), b).has_value());
1937  EXPECT_EQ(IRect::Intersection(std::optional(a), b).value(), i);
1938 
1939  // OptRect, OptRect
1940  EXPECT_TRUE(
1941  IRect::Intersection(std::optional(a), std::optional(b)).has_value());
1942  EXPECT_EQ(IRect::Intersection(std::optional(a), std::optional(b)).value(),
1943  i);
1944  };
1945 
1946  test2(a, b, IRect::MakeLTRB(100, 100, 110, 110));
1947  test2(a, c, IRect::MakeLTRB(100, 0, 110, 110));
1948  test2(b, c, IRect::MakeLTRB(100, 100, 200, 110));
1949 }

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

◆ TEST() [293/465]

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

Definition at line 1569 of file rect_unittests.cc.

1569  {
1570  auto a = IRect::MakeLTRB(0, 0, 100, 100);
1571  auto b = IRect::MakeLTRB(100, 100, 200, 200);
1572  auto c = IRect::MakeLTRB(100, 0, 200, 100);
1573 
1574  // NullOpt, NullOpt
1575  EXPECT_FALSE(IRect::Union(std::nullopt, std::nullopt).has_value());
1576  EXPECT_EQ(IRect::Union(std::nullopt, std::nullopt), std::nullopt);
1577 
1578  auto test1 = [](const IRect& r) {
1579  // Rect, NullOpt
1580  EXPECT_EQ(IRect::Union(r, std::nullopt), r);
1581 
1582  // OptRect, NullOpt
1583  EXPECT_TRUE(IRect::Union(std::optional(r), std::nullopt).has_value());
1584  EXPECT_EQ(IRect::Union(std::optional(r), std::nullopt).value(), r);
1585 
1586  // NullOpt, Rect
1587  EXPECT_EQ(IRect::Union(std::nullopt, r), r);
1588 
1589  // NullOpt, OptRect
1590  EXPECT_TRUE(IRect::Union(std::nullopt, std::optional(r)).has_value());
1591  EXPECT_EQ(IRect::Union(std::nullopt, std::optional(r)).value(), r);
1592  };
1593 
1594  test1(a);
1595  test1(b);
1596  test1(c);
1597 
1598  auto test2 = [](const IRect& a, const IRect& b, const IRect& u) {
1599  ASSERT_EQ(a.Union(b), u);
1600 
1601  // Rect, OptRect
1602  EXPECT_EQ(IRect::Union(a, std::optional(b)), u);
1603 
1604  // OptRect, Rect
1605  EXPECT_EQ(IRect::Union(std::optional(a), b), u);
1606 
1607  // OptRect, OptRect
1608  EXPECT_TRUE(IRect::Union(std::optional(a), std::optional(b)).has_value());
1609  EXPECT_EQ(IRect::Union(std::optional(a), std::optional(b)).value(), u);
1610  };
1611 
1612  test2(a, b, IRect::MakeLTRB(0, 0, 200, 200));
1613  test2(a, c, IRect::MakeLTRB(0, 0, 200, 100));
1614  test2(b, c, IRect::MakeLTRB(100, 0, 200, 200));
1615 }

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

◆ TEST() [294/465]

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

Definition at line 1746 of file rect_unittests.cc.

1746  {
1747  auto a = Rect::MakeLTRB(0, 0, 110, 110);
1748  auto b = Rect::MakeLTRB(100, 100, 200, 200);
1749  auto c = Rect::MakeLTRB(100, 0, 200, 110);
1750 
1751  // NullOpt, NullOpt
1752  EXPECT_FALSE(Rect::Intersection(std::nullopt, std::nullopt).has_value());
1753  EXPECT_EQ(Rect::Intersection(std::nullopt, std::nullopt), std::nullopt);
1754 
1755  auto test1 = [](const Rect& r) {
1756  // Rect, NullOpt
1757  EXPECT_TRUE(Rect::Intersection(r, std::nullopt).has_value());
1758  EXPECT_EQ(Rect::Intersection(r, std::nullopt).value(), r);
1759 
1760  // OptRect, NullOpt
1761  EXPECT_TRUE(Rect::Intersection(std::optional(r), std::nullopt).has_value());
1762  EXPECT_EQ(Rect::Intersection(std::optional(r), std::nullopt).value(), r);
1763 
1764  // NullOpt, Rect
1765  EXPECT_TRUE(Rect::Intersection(std::nullopt, r).has_value());
1766  EXPECT_EQ(Rect::Intersection(std::nullopt, r).value(), r);
1767 
1768  // NullOpt, OptRect
1769  EXPECT_TRUE(Rect::Intersection(std::nullopt, std::optional(r)).has_value());
1770  EXPECT_EQ(Rect::Intersection(std::nullopt, std::optional(r)).value(), r);
1771  };
1772 
1773  test1(a);
1774  test1(b);
1775  test1(c);
1776 
1777  auto test2 = [](const Rect& a, const Rect& b, const Rect& i) {
1778  ASSERT_EQ(a.Intersection(b), i);
1779 
1780  // Rect, OptRect
1781  EXPECT_TRUE(Rect::Intersection(a, std::optional(b)).has_value());
1782  EXPECT_EQ(Rect::Intersection(a, std::optional(b)).value(), i);
1783 
1784  // OptRect, Rect
1785  EXPECT_TRUE(Rect::Intersection(std::optional(a), b).has_value());
1786  EXPECT_EQ(Rect::Intersection(std::optional(a), b).value(), i);
1787 
1788  // OptRect, OptRect
1789  EXPECT_TRUE(
1790  Rect::Intersection(std::optional(a), std::optional(b)).has_value());
1791  EXPECT_EQ(Rect::Intersection(std::optional(a), std::optional(b)).value(),
1792  i);
1793  };
1794 
1795  test2(a, b, Rect::MakeLTRB(100, 100, 110, 110));
1796  test2(a, c, Rect::MakeLTRB(100, 0, 110, 110));
1797  test2(b, c, Rect::MakeLTRB(100, 100, 200, 110));
1798 }

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

◆ TEST() [295/465]

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

Definition at line 1449 of file rect_unittests.cc.

1449  {
1450  auto a = Rect::MakeLTRB(0, 0, 100, 100);
1451  auto b = Rect::MakeLTRB(100, 100, 200, 200);
1452  auto c = Rect::MakeLTRB(100, 0, 200, 100);
1453 
1454  // NullOpt, NullOpt
1455  EXPECT_FALSE(Rect::Union(std::nullopt, std::nullopt).has_value());
1456  EXPECT_EQ(Rect::Union(std::nullopt, std::nullopt), std::nullopt);
1457 
1458  auto test1 = [](const Rect& r) {
1459  // Rect, NullOpt
1460  EXPECT_EQ(Rect::Union(r, std::nullopt), r);
1461 
1462  // OptRect, NullOpt
1463  EXPECT_TRUE(Rect::Union(std::optional(r), std::nullopt).has_value());
1464  EXPECT_EQ(Rect::Union(std::optional(r), std::nullopt).value(), r);
1465 
1466  // NullOpt, Rect
1467  EXPECT_EQ(Rect::Union(std::nullopt, r), r);
1468 
1469  // NullOpt, OptRect
1470  EXPECT_TRUE(Rect::Union(std::nullopt, std::optional(r)).has_value());
1471  EXPECT_EQ(Rect::Union(std::nullopt, std::optional(r)).value(), r);
1472  };
1473 
1474  test1(a);
1475  test1(b);
1476  test1(c);
1477 
1478  auto test2 = [](const Rect& a, const Rect& b, const Rect& u) {
1479  ASSERT_EQ(a.Union(b), u);
1480 
1481  // Rect, OptRect
1482  EXPECT_EQ(Rect::Union(a, std::optional(b)), u);
1483 
1484  // OptRect, Rect
1485  EXPECT_EQ(Rect::Union(std::optional(a), b), u);
1486 
1487  // OptRect, OptRect
1488  EXPECT_TRUE(Rect::Union(std::optional(a), std::optional(b)).has_value());
1489  EXPECT_EQ(Rect::Union(std::optional(a), std::optional(b)).value(), u);
1490  };
1491 
1492  test2(a, b, Rect::MakeLTRB(0, 0, 200, 200));
1493  test2(a, c, Rect::MakeLTRB(0, 0, 200, 100));
1494  test2(b, c, Rect::MakeLTRB(100, 0, 200, 200));
1495 }

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

◆ TEST() [296/465]

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

Definition at line 1016 of file rect_unittests.cc.

1016  {
1017  EXPECT_EQ(Rect::MakeXYWH(0, 0, 100, 200).Area(), 20000);
1018  EXPECT_EQ(Rect::MakeXYWH(10, 20, 100, 200).Area(), 20000);
1019  EXPECT_EQ(Rect::MakeXYWH(0, 0, 200, 100).Area(), 20000);
1020  EXPECT_EQ(Rect::MakeXYWH(10, 20, 200, 100).Area(), 20000);
1021  EXPECT_EQ(Rect::MakeXYWH(0, 0, 100, 100).Area(), 10000);
1022  EXPECT_EQ(Rect::MakeXYWH(10, 20, 100, 100).Area(), 10000);
1023 }

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

◆ TEST() [297/465]

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

Definition at line 2311 of file rect_unittests.cc.

2311  {
2312  auto check_nans = [](const Rect& rect, const Point& point,
2313  const std::string& label) {
2314  ASSERT_TRUE(rect.IsFinite()) << label;
2315  ASSERT_TRUE(point.IsFinite()) << label;
2316 
2317  for (int i = 1; i < 16; i++) {
2318  EXPECT_FALSE(swap_nan(rect, i).ContainsInclusive(point))
2319  << label << ", index = " << i;
2320  for (int j = 1; j < 4; j++) {
2321  EXPECT_FALSE(swap_nan(rect, i).ContainsInclusive(swap_nan(point, j)))
2322  << label << ", indices = " << i << ", " << j;
2323  }
2324  }
2325  };
2326 
2327  auto check_empty_flips = [](const Rect& rect, const Point& point,
2328  const std::string& label) {
2329  ASSERT_FALSE(rect.IsEmpty());
2330 
2331  EXPECT_FALSE(flip_lr(rect).ContainsInclusive(point)) << label;
2332  EXPECT_FALSE(flip_tb(rect).ContainsInclusive(point)) << label;
2333  EXPECT_FALSE(flip_lrtb(rect).ContainsInclusive(point)) << label;
2334  };
2335 
2336  auto test_inside = [&check_nans, &check_empty_flips](const Rect& rect,
2337  const Point& point) {
2338  ASSERT_FALSE(rect.IsEmpty()) << rect;
2339 
2340  std::stringstream stream;
2341  stream << rect << " contains " << point;
2342  auto label = stream.str();
2343 
2344  EXPECT_TRUE(rect.ContainsInclusive(point)) << label;
2345  check_empty_flips(rect, point, label);
2346  check_nans(rect, point, label);
2347  };
2348 
2349  auto test_outside = [&check_nans, &check_empty_flips](const Rect& rect,
2350  const Point& point) {
2351  ASSERT_FALSE(rect.IsEmpty()) << rect;
2352 
2353  std::stringstream stream;
2354  stream << rect << " contains " << point;
2355  auto label = stream.str();
2356 
2357  EXPECT_FALSE(rect.ContainsInclusive(point)) << label;
2358  check_empty_flips(rect, point, label);
2359  check_nans(rect, point, label);
2360  };
2361 
2362  {
2363  // Origin is inclusive
2364  auto r = Rect::MakeXYWH(100, 100, 100, 100);
2365  auto p = Point(100, 100);
2366 
2367  test_inside(r, p);
2368  }
2369  {
2370  // Size is inclusive
2371  auto r = Rect::MakeXYWH(100, 100, 100, 100);
2372  auto p = Point(200, 200);
2373 
2374  test_inside(r, p);
2375  }
2376  {
2377  // Size + epsilon is exclusive
2378  auto r = Rect::MakeXYWH(100, 100, 100, 100);
2379  auto p = Point(200 + kEhCloseEnough, 200 + kEhCloseEnough);
2380 
2381  test_outside(r, p);
2382  }
2383  {
2384  auto r = Rect::MakeXYWH(100, 100, 100, 100);
2385  auto p = Point(99, 99);
2386 
2387  test_outside(r, p);
2388  }
2389  {
2390  auto r = Rect::MakeXYWH(100, 100, 100, 100);
2391  auto p = Point(199, 199);
2392 
2393  test_inside(r, p);
2394  }
2395 
2396  {
2397  auto r = Rect::MakeMaximum();
2398  auto p = Point(199, 199);
2399 
2400  test_inside(r, p);
2401  }
2402 }
static constexpr Point swap_nan(const Point &point, int index)

References impeller::TRect< T >::ContainsInclusive(), flip_lr(), flip_lrtb(), flip_tb(), impeller::TRect< T >::IsEmpty(), impeller::TRect< T >::IsFinite(), impeller::kEhCloseEnough, impeller::TRect< Scalar >::MakeMaximum(), impeller::TRect< Scalar >::MakeXYWH(), and swap_nan().

◆ TEST() [298/465]

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

Definition at line 2156 of file rect_unittests.cc.

2156  {
2157  auto check_nans = [](const Rect& rect, const Point& point,
2158  const std::string& label) {
2159  ASSERT_TRUE(rect.IsFinite()) << label;
2160  ASSERT_TRUE(point.IsFinite()) << label;
2161 
2162  for (int i = 1; i < 16; i++) {
2163  EXPECT_FALSE(swap_nan(rect, i).Contains(point))
2164  << label << ", index = " << i;
2165  for (int j = 1; j < 4; j++) {
2166  EXPECT_FALSE(swap_nan(rect, i).Contains(swap_nan(point, j)))
2167  << label << ", indices = " << i << ", " << j;
2168  }
2169  }
2170  };
2171 
2172  auto check_empty_flips = [](const Rect& rect, const Point& point,
2173  const std::string& label) {
2174  ASSERT_FALSE(rect.IsEmpty());
2175 
2176  EXPECT_FALSE(flip_lr(rect).Contains(point)) << label;
2177  EXPECT_FALSE(flip_tb(rect).Contains(point)) << label;
2178  EXPECT_FALSE(flip_lrtb(rect).Contains(point)) << label;
2179  };
2180 
2181  auto test_inside = [&check_nans, &check_empty_flips](const Rect& rect,
2182  const Point& point) {
2183  ASSERT_FALSE(rect.IsEmpty()) << rect;
2184 
2185  std::stringstream stream;
2186  stream << rect << " contains " << point;
2187  auto label = stream.str();
2188 
2189  EXPECT_TRUE(rect.Contains(point)) << label;
2190  check_empty_flips(rect, point, label);
2191  check_nans(rect, point, label);
2192  };
2193 
2194  auto test_outside = [&check_nans, &check_empty_flips](const Rect& rect,
2195  const Point& point) {
2196  ASSERT_FALSE(rect.IsEmpty()) << rect;
2197 
2198  std::stringstream stream;
2199  stream << rect << " contains " << point;
2200  auto label = stream.str();
2201 
2202  EXPECT_FALSE(rect.Contains(point)) << label;
2203  check_empty_flips(rect, point, label);
2204  check_nans(rect, point, label);
2205  };
2206 
2207  {
2208  // Origin is inclusive
2209  auto r = Rect::MakeXYWH(100, 100, 100, 100);
2210  auto p = Point(100, 100);
2211 
2212  test_inside(r, p);
2213  }
2214  {
2215  // Size is exclusive
2216  auto r = Rect::MakeXYWH(100, 100, 100, 100);
2217  auto p = Point(200, 200);
2218 
2219  test_outside(r, p);
2220  }
2221  {
2222  auto r = Rect::MakeXYWH(100, 100, 100, 100);
2223  auto p = Point(99, 99);
2224 
2225  test_outside(r, p);
2226  }
2227  {
2228  auto r = Rect::MakeXYWH(100, 100, 100, 100);
2229  auto p = Point(199, 199);
2230 
2231  test_inside(r, p);
2232  }
2233 
2234  {
2235  auto r = Rect::MakeMaximum();
2236  auto p = Point(199, 199);
2237 
2238  test_inside(r, p);
2239  }
2240 }

References impeller::TRect< T >::Contains(), flip_lr(), flip_lrtb(), flip_tb(), impeller::TRect< T >::IsEmpty(), impeller::TRect< T >::IsFinite(), impeller::TRect< Scalar >::MakeMaximum(), impeller::TRect< Scalar >::MakeXYWH(), and swap_nan().

◆ TEST() [299/465]

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

Definition at line 2480 of file rect_unittests.cc.

2480  {
2481  auto check_nans = [](const Rect& a, const Rect& b, const std::string& label) {
2482  ASSERT_TRUE(a.IsFinite()) << label;
2483  ASSERT_TRUE(b.IsFinite()) << label;
2484  ASSERT_FALSE(a.IsEmpty());
2485 
2486  for (int i = 1; i < 16; i++) {
2487  // NaN in a produces false
2488  EXPECT_FALSE(swap_nan(a, i).Contains(b)) << label << ", index = " << i;
2489  // NaN in b produces false
2490  EXPECT_TRUE(a.Contains(swap_nan(b, i))) << label << ", index = " << i;
2491  // NaN in both is false
2492  for (int j = 1; j < 16; j++) {
2493  EXPECT_FALSE(swap_nan(a, i).Contains(swap_nan(b, j)))
2494  << label << ", indices = " << i << ", " << j;
2495  }
2496  }
2497  };
2498 
2499  auto check_empty_flips = [](const Rect& a, const Rect& b,
2500  const std::string& label) {
2501  ASSERT_FALSE(a.IsEmpty());
2502  // test b rects are allowed to have 0 w/h, but not be backwards
2503  ASSERT_FALSE(b.GetLeft() > b.GetRight() || b.GetTop() > b.GetBottom());
2504 
2505  // unflipped a vs flipped (empty) b yields false
2506  EXPECT_TRUE(a.Contains(flip_lr(b))) << label;
2507  EXPECT_TRUE(a.Contains(flip_tb(b))) << label;
2508  EXPECT_TRUE(a.Contains(flip_lrtb(b))) << label;
2509 
2510  // flipped (empty) a vs unflipped b yields false
2511  EXPECT_FALSE(flip_lr(a).Contains(b)) << label;
2512  EXPECT_FALSE(flip_tb(a).Contains(b)) << label;
2513  EXPECT_FALSE(flip_lrtb(a).Contains(b)) << label;
2514 
2515  // flipped (empty) a vs flipped (empty) b yields empty
2516  EXPECT_FALSE(flip_lr(a).Contains(flip_lr(b))) << label;
2517  EXPECT_FALSE(flip_tb(a).Contains(flip_tb(b))) << label;
2518  EXPECT_FALSE(flip_lrtb(a).Contains(flip_lrtb(b))) << label;
2519  };
2520 
2521  auto test_inside = [&check_nans, &check_empty_flips](const Rect& a,
2522  const Rect& b) {
2523  ASSERT_FALSE(a.IsEmpty()) << a;
2524  // test b rects are allowed to have 0 w/h, but not be backwards
2525  ASSERT_FALSE(b.GetLeft() > b.GetRight() || b.GetTop() > b.GetBottom());
2526 
2527  std::stringstream stream;
2528  stream << a << " contains " << b;
2529  auto label = stream.str();
2530 
2531  EXPECT_TRUE(a.Contains(b)) << label;
2532  check_empty_flips(a, b, label);
2533  check_nans(a, b, label);
2534  };
2535 
2536  auto test_not_inside = [&check_nans, &check_empty_flips](const Rect& a,
2537  const Rect& b) {
2538  ASSERT_FALSE(a.IsEmpty()) << a;
2539  // If b was empty, it would be contained and should not be tested with
2540  // this function - use |test_inside| instead.
2541  ASSERT_FALSE(b.IsEmpty()) << b;
2542 
2543  std::stringstream stream;
2544  stream << a << " contains " << b;
2545  auto label = stream.str();
2546 
2547  EXPECT_FALSE(a.Contains(b)) << label;
2548  check_empty_flips(a, b, label);
2549  check_nans(a, b, label);
2550  };
2551 
2552  {
2553  auto a = Rect::MakeXYWH(100, 100, 100, 100);
2554 
2555  test_inside(a, a);
2556  }
2557  {
2558  auto a = Rect::MakeXYWH(100, 100, 100, 100);
2559  auto b = Rect::MakeXYWH(0, 0, 0, 0);
2560 
2561  test_inside(a, b);
2562  }
2563  {
2564  auto a = Rect::MakeXYWH(100, 100, 100, 100);
2565  auto b = Rect::MakeXYWH(150, 150, 20, 20);
2566 
2567  test_inside(a, b);
2568  }
2569  {
2570  auto a = Rect::MakeXYWH(100, 100, 100, 100);
2571  auto b = Rect::MakeXYWH(150, 150, 100, 100);
2572 
2573  test_not_inside(a, b);
2574  }
2575  {
2576  auto a = Rect::MakeXYWH(100, 100, 100, 100);
2577  auto b = Rect::MakeXYWH(50, 50, 100, 100);
2578 
2579  test_not_inside(a, b);
2580  }
2581  {
2582  auto a = Rect::MakeXYWH(100, 100, 100, 100);
2583  auto b = Rect::MakeXYWH(0, 0, 300, 300);
2584 
2585  test_not_inside(a, b);
2586  }
2587  {
2588  auto a = Rect::MakeMaximum();
2589  auto b = Rect::MakeXYWH(0, 0, 300, 300);
2590 
2591  test_inside(a, b);
2592  }
2593 }

References impeller::saturated::b, impeller::TRect< T >::Contains(), flip_lr(), flip_lrtb(), flip_tb(), impeller::TRect< T >::IsEmpty(), impeller::TRect< T >::IsFinite(), impeller::TRect< Scalar >::MakeMaximum(), impeller::TRect< Scalar >::MakeXYWH(), and swap_nan().

◆ TEST() [300/465]

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

Definition at line 668 of file rect_unittests.cc.

668  {
669  // Using fractional-power-of-2 friendly values for equality tests
670  Rect rect = Rect::MakeLTRB(5.125f, 10.25f, 20.625f, 25.375f);
671  Rect copy = rect;
672 
673  EXPECT_EQ(rect, copy);
674  EXPECT_EQ(copy.GetLeft(), 5.125f);
675  EXPECT_EQ(copy.GetTop(), 10.25f);
676  EXPECT_EQ(copy.GetRight(), 20.625f);
677  EXPECT_EQ(copy.GetBottom(), 25.375f);
678  EXPECT_EQ(copy.GetX(), 5.125f);
679  EXPECT_EQ(copy.GetY(), 10.25f);
680  EXPECT_EQ(copy.GetWidth(), 15.5f);
681  EXPECT_EQ(copy.GetHeight(), 15.125f);
682  EXPECT_FALSE(copy.IsEmpty());
683  EXPECT_TRUE(copy.IsFinite());
684 }

References impeller::TRect< T >::GetBottom(), impeller::TRect< T >::GetHeight(), impeller::TRect< T >::GetLeft(), impeller::TRect< T >::GetRight(), impeller::TRect< T >::GetTop(), impeller::TRect< T >::GetWidth(), impeller::TRect< T >::GetX(), impeller::TRect< T >::GetY(), impeller::TRect< T >::IsEmpty(), impeller::TRect< T >::IsFinite(), and impeller::TRect< Scalar >::MakeLTRB().

◆ TEST() [301/465]

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

Definition at line 2688 of file rect_unittests.cc.

2688  {
2689  Rect cull_rect = Rect::MakeLTRB(20, 20, 40, 40);
2690 
2691  auto check_nans = [&cull_rect](const Rect& diff_rect,
2692  const std::string& label) {
2693  EXPECT_TRUE(cull_rect.IsFinite()) << label;
2694  EXPECT_TRUE(diff_rect.IsFinite()) << label;
2695 
2696  for (int i = 1; i < 16; i++) {
2697  // NaN in cull_rect produces empty
2698  EXPECT_FALSE(swap_nan(cull_rect, i).Cutout(diff_rect).has_value())
2699  << label << ", index " << i;
2700  EXPECT_EQ(swap_nan(cull_rect, i).CutoutOrEmpty(diff_rect), Rect())
2701  << label << ", index " << i;
2702 
2703  // NaN in diff_rect is nop
2704  EXPECT_TRUE(cull_rect.Cutout(swap_nan(diff_rect, i)).has_value())
2705  << label << ", index " << i;
2706  EXPECT_EQ(cull_rect.CutoutOrEmpty(swap_nan(diff_rect, i)), cull_rect)
2707  << label << ", index " << i;
2708 
2709  for (int j = 1; j < 16; j++) {
2710  // NaN in both is also empty
2711  EXPECT_FALSE(
2712  swap_nan(cull_rect, i).Cutout(swap_nan(diff_rect, j)).has_value())
2713  << label << ", indices " << i << ", " << j;
2714  EXPECT_EQ(swap_nan(cull_rect, i).CutoutOrEmpty(swap_nan(diff_rect, j)),
2715  Rect())
2716  << label << ", indices " << i << ", " << j;
2717  }
2718  }
2719  };
2720 
2721  auto check_empty_flips = [&cull_rect](const Rect& diff_rect,
2722  const std::string& label) {
2723  EXPECT_FALSE(cull_rect.IsEmpty()) << label;
2724  EXPECT_FALSE(diff_rect.IsEmpty()) << label;
2725 
2726  // unflipped cull_rect vs flipped(empty) diff_rect
2727  // == cull_rect
2728  EXPECT_TRUE(cull_rect.Cutout(flip_lr(diff_rect)).has_value()) << label;
2729  EXPECT_EQ(cull_rect.Cutout(flip_lr(diff_rect)), cull_rect) << label;
2730  EXPECT_TRUE(cull_rect.Cutout(flip_tb(diff_rect)).has_value()) << label;
2731  EXPECT_EQ(cull_rect.Cutout(flip_tb(diff_rect)), cull_rect) << label;
2732  EXPECT_TRUE(cull_rect.Cutout(flip_lrtb(diff_rect)).has_value()) << label;
2733  EXPECT_EQ(cull_rect.Cutout(flip_lrtb(diff_rect)), cull_rect) << label;
2734 
2735  // flipped(empty) cull_rect vs unflipped diff_rect
2736  // == empty
2737  EXPECT_FALSE(flip_lr(cull_rect).Cutout(diff_rect).has_value()) << label;
2738  EXPECT_EQ(flip_lr(cull_rect).CutoutOrEmpty(diff_rect), Rect()) << label;
2739  EXPECT_FALSE(flip_tb(cull_rect).Cutout(diff_rect).has_value()) << label;
2740  EXPECT_EQ(flip_tb(cull_rect).CutoutOrEmpty(diff_rect), Rect()) << label;
2741  EXPECT_FALSE(flip_lrtb(cull_rect).Cutout(diff_rect).has_value()) << label;
2742  EXPECT_EQ(flip_lrtb(cull_rect).CutoutOrEmpty(diff_rect), Rect()) << label;
2743 
2744  // flipped(empty) cull_rect vs flipped(empty) diff_rect
2745  // == empty
2746  EXPECT_FALSE(flip_lr(cull_rect).Cutout(flip_lr(diff_rect)).has_value())
2747  << label;
2748  EXPECT_EQ(flip_lr(cull_rect).CutoutOrEmpty(flip_lr(diff_rect)), Rect())
2749  << label;
2750  EXPECT_FALSE(flip_tb(cull_rect).Cutout(flip_tb(diff_rect)).has_value())
2751  << label;
2752  EXPECT_EQ(flip_tb(cull_rect).CutoutOrEmpty(flip_tb(diff_rect)), Rect())
2753  << label;
2754  EXPECT_FALSE(flip_lrtb(cull_rect).Cutout(flip_lrtb(diff_rect)).has_value())
2755  << label;
2756  EXPECT_EQ(flip_lrtb(cull_rect).CutoutOrEmpty(flip_lrtb(diff_rect)), Rect())
2757  << label;
2758  };
2759 
2760  auto non_reducing = [&cull_rect, &check_empty_flips, &check_nans](
2761  const Rect& diff_rect, const std::string& label) {
2762  EXPECT_EQ(cull_rect.Cutout(diff_rect), cull_rect) << label;
2763  EXPECT_EQ(cull_rect.CutoutOrEmpty(diff_rect), cull_rect) << label;
2764  check_empty_flips(diff_rect, label);
2765  check_nans(diff_rect, label);
2766  };
2767 
2768  auto reducing = [&cull_rect, &check_empty_flips, &check_nans](
2769  const Rect& diff_rect, const Rect& result_rect,
2770  const std::string& label) {
2771  EXPECT_TRUE(!result_rect.IsEmpty());
2772  EXPECT_EQ(cull_rect.Cutout(diff_rect), result_rect) << label;
2773  EXPECT_EQ(cull_rect.CutoutOrEmpty(diff_rect), result_rect) << label;
2774  check_empty_flips(diff_rect, label);
2775  check_nans(diff_rect, label);
2776  };
2777 
2778  auto emptying = [&cull_rect, &check_empty_flips, &check_nans](
2779  const Rect& diff_rect, const std::string& label) {
2780  EXPECT_FALSE(cull_rect.Cutout(diff_rect).has_value()) << label;
2781  EXPECT_EQ(cull_rect.CutoutOrEmpty(diff_rect), Rect()) << label;
2782  check_empty_flips(diff_rect, label);
2783  check_nans(diff_rect, label);
2784  };
2785 
2786  // Skim the corners and edge
2787  non_reducing(Rect::MakeLTRB(10, 10, 20, 20), "outside UL corner");
2788  non_reducing(Rect::MakeLTRB(20, 10, 40, 20), "Above");
2789  non_reducing(Rect::MakeLTRB(40, 10, 50, 20), "outside UR corner");
2790  non_reducing(Rect::MakeLTRB(40, 20, 50, 40), "Right");
2791  non_reducing(Rect::MakeLTRB(40, 40, 50, 50), "outside LR corner");
2792  non_reducing(Rect::MakeLTRB(20, 40, 40, 50), "Below");
2793  non_reducing(Rect::MakeLTRB(10, 40, 20, 50), "outside LR corner");
2794  non_reducing(Rect::MakeLTRB(10, 20, 20, 40), "Left");
2795 
2796  // Overlap corners
2797  non_reducing(Rect::MakeLTRB(15, 15, 25, 25), "covering UL corner");
2798  non_reducing(Rect::MakeLTRB(35, 15, 45, 25), "covering UR corner");
2799  non_reducing(Rect::MakeLTRB(35, 35, 45, 45), "covering LR corner");
2800  non_reducing(Rect::MakeLTRB(15, 35, 25, 45), "covering LL corner");
2801 
2802  // Overlap edges, but not across an entire side
2803  non_reducing(Rect::MakeLTRB(20, 15, 39, 25), "Top edge left-biased");
2804  non_reducing(Rect::MakeLTRB(21, 15, 40, 25), "Top edge, right biased");
2805  non_reducing(Rect::MakeLTRB(35, 20, 45, 39), "Right edge, top-biased");
2806  non_reducing(Rect::MakeLTRB(35, 21, 45, 40), "Right edge, bottom-biased");
2807  non_reducing(Rect::MakeLTRB(20, 35, 39, 45), "Bottom edge, left-biased");
2808  non_reducing(Rect::MakeLTRB(21, 35, 40, 45), "Bottom edge, right-biased");
2809  non_reducing(Rect::MakeLTRB(15, 20, 25, 39), "Left edge, top-biased");
2810  non_reducing(Rect::MakeLTRB(15, 21, 25, 40), "Left edge, bottom-biased");
2811 
2812  // Slice all the way through the middle
2813  non_reducing(Rect::MakeLTRB(25, 15, 35, 45), "Vertical interior slice");
2814  non_reducing(Rect::MakeLTRB(15, 25, 45, 35), "Horizontal interior slice");
2815 
2816  // Slice off each edge
2817  reducing(Rect::MakeLTRB(20, 15, 40, 25), //
2818  Rect::MakeLTRB(20, 25, 40, 40), //
2819  "Slice off top");
2820  reducing(Rect::MakeLTRB(35, 20, 45, 40), //
2821  Rect::MakeLTRB(20, 20, 35, 40), //
2822  "Slice off right");
2823  reducing(Rect::MakeLTRB(20, 35, 40, 45), //
2824  Rect::MakeLTRB(20, 20, 40, 35), //
2825  "Slice off bottom");
2826  reducing(Rect::MakeLTRB(15, 20, 25, 40), //
2827  Rect::MakeLTRB(25, 20, 40, 40), //
2828  "Slice off left");
2829 
2830  // cull rect contains diff rect
2831  non_reducing(Rect::MakeLTRB(21, 21, 39, 39), "Contained, non-covering");
2832 
2833  // cull rect equals diff rect
2834  emptying(cull_rect, "Perfectly covering");
2835 
2836  // diff rect contains cull rect
2837  emptying(Rect::MakeLTRB(15, 15, 45, 45), "Smothering");
2838 }

References impeller::TRect< T >::Cutout(), impeller::TRect< T >::CutoutOrEmpty(), flip_lr(), flip_lrtb(), flip_tb(), impeller::TRect< T >::IsEmpty(), impeller::TRect< T >::IsFinite(), impeller::TRect< Scalar >::MakeLTRB(), and swap_nan().

◆ TEST() [302/465]

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

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

Definition at line 3030 of file rect_unittests.cc.

3030  {
3031  auto r = Rect::MakeLTRB(1, 2, 3, 4);
3032 
3033  EXPECT_EQ(r.GetLeft(), 1);
3034  EXPECT_EQ(r.GetTop(), 2);
3035  EXPECT_EQ(r.GetRight(), 3);
3036  EXPECT_EQ(r.GetBottom(), 4);
3037 
3038  EXPECT_POINT_NEAR(r.GetLeftTop(), Point(1, 2));
3039  EXPECT_POINT_NEAR(r.GetRightTop(), Point(3, 2));
3040  EXPECT_POINT_NEAR(r.GetLeftBottom(), Point(1, 4));
3041  EXPECT_POINT_NEAR(r.GetRightBottom(), Point(3, 4));
3042 }

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

◆ TEST() [304/465]

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

Definition at line 809 of file rect_unittests.cc.

809  {
810  Rect rect = Rect::MakeLTRB(50, 50, 100, 100);
811 
812  auto test = [&rect](Scalar l, Scalar t, Scalar r, Scalar b,
813  const std::string& label) {
814  EXPECT_FALSE(rect.IntersectsWithRect(Rect::MakeLTRB(l, b, r, t)))
815  << label << " with Top/Bottom swapped";
816  EXPECT_FALSE(rect.IntersectsWithRect(Rect::MakeLTRB(r, b, l, t)))
817  << label << " with Left/Right swapped";
818  EXPECT_FALSE(rect.IntersectsWithRect(Rect::MakeLTRB(r, t, l, b)))
819  << label << " with all sides swapped";
820  };
821 
822  test(20, 20, 30, 30, "Above and Left");
823  test(70, 20, 80, 30, "Above");
824  test(120, 20, 130, 30, "Above and Right");
825  test(120, 70, 130, 80, "Right");
826  test(120, 120, 130, 130, "Below and Right");
827  test(70, 120, 80, 130, "Below");
828  test(20, 120, 30, 130, "Below and Left");
829  test(20, 70, 30, 80, "Left");
830 
831  test(70, 70, 80, 80, "Inside");
832 
833  test(40, 70, 60, 80, "Straddling Left");
834  test(70, 40, 80, 60, "Straddling Top");
835  test(90, 70, 110, 80, "Straddling Right");
836  test(70, 90, 80, 110, "Straddling Bottom");
837 }

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

◆ TEST() [305/465]

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

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

Definition at line 1250 of file rect_unittests.cc.

1250  {
1251  auto rect = Rect::MakeLTRB(100, 100, 200, 200);
1252 
1253  // Expand(T amount)
1254  EXPECT_EQ(rect.Expand(10), Rect::MakeLTRB(90, 90, 210, 210));
1255  EXPECT_EQ(rect.Expand(-10), Rect::MakeLTRB(110, 110, 190, 190));
1256 
1257  // Expand(amount, amount)
1258  EXPECT_EQ(rect.Expand(10, 10), Rect::MakeLTRB(90, 90, 210, 210));
1259  EXPECT_EQ(rect.Expand(10, -10), Rect::MakeLTRB(90, 110, 210, 190));
1260  EXPECT_EQ(rect.Expand(-10, 10), Rect::MakeLTRB(110, 90, 190, 210));
1261  EXPECT_EQ(rect.Expand(-10, -10), Rect::MakeLTRB(110, 110, 190, 190));
1262 
1263  // Expand(amount, amount, amount, amount)
1264  EXPECT_EQ(rect.Expand(10, 20, 30, 40), Rect::MakeLTRB(90, 80, 230, 240));
1265  EXPECT_EQ(rect.Expand(-10, 20, 30, 40), Rect::MakeLTRB(110, 80, 230, 240));
1266  EXPECT_EQ(rect.Expand(10, -20, 30, 40), Rect::MakeLTRB(90, 120, 230, 240));
1267  EXPECT_EQ(rect.Expand(10, 20, -30, 40), Rect::MakeLTRB(90, 80, 170, 240));
1268  EXPECT_EQ(rect.Expand(10, 20, 30, -40), Rect::MakeLTRB(90, 80, 230, 160));
1269 
1270  // Expand(Point amount)
1271  EXPECT_EQ(rect.Expand(Point{10, 10}), Rect::MakeLTRB(90, 90, 210, 210));
1272  EXPECT_EQ(rect.Expand(Point{10, -10}), Rect::MakeLTRB(90, 110, 210, 190));
1273  EXPECT_EQ(rect.Expand(Point{-10, 10}), Rect::MakeLTRB(110, 90, 190, 210));
1274  EXPECT_EQ(rect.Expand(Point{-10, -10}), Rect::MakeLTRB(110, 110, 190, 190));
1275 
1276  // Expand(Size amount)
1277  EXPECT_EQ(rect.Expand(Size{10, 10}), Rect::MakeLTRB(90, 90, 210, 210));
1278  EXPECT_EQ(rect.Expand(Size{10, -10}), Rect::MakeLTRB(90, 110, 210, 190));
1279  EXPECT_EQ(rect.Expand(Size{-10, 10}), Rect::MakeLTRB(110, 90, 190, 210));
1280  EXPECT_EQ(rect.Expand(Size{-10, -10}), Rect::MakeLTRB(110, 110, 190, 190));
1281 }

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

◆ TEST() [307/465]

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

Definition at line 164 of file rect_unittests.cc.

164  {
165  IRect irect = IRect::MakeLTRB(10, 20, 30, 40);
166  Rect rect = Rect::Make(irect);
167 
168  EXPECT_EQ(rect.GetLeft(), 10);
169  EXPECT_EQ(rect.GetTop(), 20);
170  EXPECT_EQ(rect.GetRight(), 30);
171  EXPECT_EQ(rect.GetBottom(), 40);
172 
173  // The following do not compile
174  // IRect irect2 = IRect::Make(rect);
175  // IRect irect2 = IRect::Make(irect);
176 }

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

◆ TEST() [308/465]

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

Definition at line 654 of file rect_unittests.cc.

654  {
655  EXPECT_EQ(Rect(Rect::MakeXYWH(2, 3, 7, 15)),
656  Rect::MakeXYWH(2.0, 3.0, 7.0, 15.0));
657  EXPECT_EQ(Rect(Rect::MakeLTRB(2, 3, 7, 15)),
658  Rect::MakeLTRB(2.0, 3.0, 7.0, 15.0));
659 }

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

◆ TEST() [309/465]

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

Definition at line 1034 of file rect_unittests.cc.

1034  {
1035  {
1036  // Checks for expected matrix values
1037 
1038  auto r = Rect::MakeXYWH(100, 200, 200, 400);
1039 
1040  EXPECT_EQ(r.GetNormalizingTransform(),
1041  Matrix::MakeScale({0.005, 0.0025, 1.0}) *
1042  Matrix::MakeTranslation({-100, -200}));
1043  }
1044 
1045  {
1046  // Checks for expected transform of points relative to the rect
1047 
1048  auto r = Rect::MakeLTRB(300, 500, 400, 700);
1049  auto m = r.GetNormalizingTransform();
1050 
1051  // The 4 corners of the rect => (0, 0) to (1, 1)
1052  EXPECT_EQ(m * Point(300, 500), Point(0, 0));
1053  EXPECT_EQ(m * Point(400, 500), Point(1, 0));
1054  EXPECT_EQ(m * Point(400, 700), Point(1, 1));
1055  EXPECT_EQ(m * Point(300, 700), Point(0, 1));
1056 
1057  // The center => (0.5, 0.5)
1058  EXPECT_EQ(m * Point(350, 600), Point(0.5, 0.5));
1059 
1060  // Outside the 4 corners => (-1, -1) to (2, 2)
1061  EXPECT_EQ(m * Point(200, 300), Point(-1, -1));
1062  EXPECT_EQ(m * Point(500, 300), Point(2, -1));
1063  EXPECT_EQ(m * Point(500, 900), Point(2, 2));
1064  EXPECT_EQ(m * Point(200, 900), Point(-1, 2));
1065  }
1066 
1067  {
1068  // Checks for behavior with empty rects
1069 
1070  auto zero = Matrix::MakeScale({0.0, 0.0, 1.0});
1071 
1072  // Empty for width and/or height == 0
1073  EXPECT_EQ(Rect::MakeXYWH(10, 10, 0, 10).GetNormalizingTransform(), zero);
1074  EXPECT_EQ(Rect::MakeXYWH(10, 10, 10, 0).GetNormalizingTransform(), zero);
1075  EXPECT_EQ(Rect::MakeXYWH(10, 10, 0, 0).GetNormalizingTransform(), zero);
1076 
1077  // Empty for width and/or height < 0
1078  EXPECT_EQ(Rect::MakeXYWH(10, 10, -1, 10).GetNormalizingTransform(), zero);
1079  EXPECT_EQ(Rect::MakeXYWH(10, 10, 10, -1).GetNormalizingTransform(), zero);
1080  EXPECT_EQ(Rect::MakeXYWH(10, 10, -1, -1).GetNormalizingTransform(), zero);
1081  }
1082 
1083  {
1084  // Checks for behavior with non-finite rects
1085 
1086  auto z = Matrix::MakeScale({0.0, 0.0, 1.0});
1087  auto nan = std::numeric_limits<Scalar>::quiet_NaN();
1088  auto inf = std::numeric_limits<Scalar>::infinity();
1089 
1090  // Non-finite for width and/or height == nan
1091  EXPECT_EQ(Rect::MakeXYWH(10, 10, nan, 10).GetNormalizingTransform(), z);
1092  EXPECT_EQ(Rect::MakeXYWH(10, 10, 10, nan).GetNormalizingTransform(), z);
1093  EXPECT_EQ(Rect::MakeXYWH(10, 10, nan, nan).GetNormalizingTransform(), z);
1094 
1095  // Non-finite for width and/or height == inf
1096  EXPECT_EQ(Rect::MakeXYWH(10, 10, inf, 10).GetNormalizingTransform(), z);
1097  EXPECT_EQ(Rect::MakeXYWH(10, 10, 10, inf).GetNormalizingTransform(), z);
1098  EXPECT_EQ(Rect::MakeXYWH(10, 10, inf, inf).GetNormalizingTransform(), z);
1099 
1100  // Non-finite for width and/or height == -inf
1101  EXPECT_EQ(Rect::MakeXYWH(10, 10, -inf, 10).GetNormalizingTransform(), z);
1102  EXPECT_EQ(Rect::MakeXYWH(10, 10, 10, -inf).GetNormalizingTransform(), z);
1103  EXPECT_EQ(Rect::MakeXYWH(10, 10, -inf, -inf).GetNormalizingTransform(), z);
1104 
1105  // Non-finite for origin X and/or Y == nan
1106  EXPECT_EQ(Rect::MakeXYWH(nan, 10, 10, 10).GetNormalizingTransform(), z);
1107  EXPECT_EQ(Rect::MakeXYWH(10, nan, 10, 10).GetNormalizingTransform(), z);
1108  EXPECT_EQ(Rect::MakeXYWH(nan, nan, 10, 10).GetNormalizingTransform(), z);
1109 
1110  // Non-finite for origin X and/or Y == inf
1111  EXPECT_EQ(Rect::MakeXYWH(inf, 10, 10, 10).GetNormalizingTransform(), z);
1112  EXPECT_EQ(Rect::MakeXYWH(10, inf, 10, 10).GetNormalizingTransform(), z);
1113  EXPECT_EQ(Rect::MakeXYWH(inf, inf, 10, 10).GetNormalizingTransform(), z);
1114 
1115  // Non-finite for origin X and/or Y == -inf
1116  EXPECT_EQ(Rect::MakeXYWH(-inf, 10, 10, 10).GetNormalizingTransform(), z);
1117  EXPECT_EQ(Rect::MakeXYWH(10, -inf, 10, 10).GetNormalizingTransform(), z);
1118  EXPECT_EQ(Rect::MakeXYWH(-inf, -inf, 10, 10).GetNormalizingTransform(), z);
1119  }
1120 }

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

◆ TEST() [310/465]

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

Definition at line 2959 of file rect_unittests.cc.

2959  {
2960  {
2961  Rect r = Rect::MakeXYWH(100, 200, 300, 400);
2962  auto points = r.GetPoints();
2963  EXPECT_POINT_NEAR(points[0], Point(100, 200));
2964  EXPECT_POINT_NEAR(points[1], Point(400, 200));
2965  EXPECT_POINT_NEAR(points[2], Point(100, 600));
2966  EXPECT_POINT_NEAR(points[3], Point(400, 600));
2967  }
2968 
2969  {
2970  Rect r = Rect::MakeMaximum();
2971  auto points = r.GetPoints();
2972  EXPECT_EQ(points[0], Point(std::numeric_limits<float>::lowest(),
2973  std::numeric_limits<float>::lowest()));
2974  EXPECT_EQ(points[1], Point(std::numeric_limits<float>::max(),
2975  std::numeric_limits<float>::lowest()));
2976  EXPECT_EQ(points[2], Point(std::numeric_limits<float>::lowest(),
2977  std::numeric_limits<float>::max()));
2978  EXPECT_EQ(points[3], Point(std::numeric_limits<float>::max(),
2979  std::numeric_limits<float>::max()));
2980  }
2981 }

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

◆ TEST() [311/465]

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

Definition at line 3016 of file rect_unittests.cc.

3016  {
3017  {
3018  Rect r = Rect::MakeXYWH(100, 200, 300, 400);
3019  auto actual = r.GetPositive();
3020  EXPECT_RECT_NEAR(r, actual);
3021  }
3022  {
3023  Rect r = Rect::MakeXYWH(100, 200, -100, -100);
3024  auto actual = r.GetPositive();
3025  Rect expected = Rect::MakeXYWH(0, 100, 100, 100);
3026  EXPECT_RECT_NEAR(expected, actual);
3027  }
3028 }

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

◆ TEST() [312/465]

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

Definition at line 2990 of file rect_unittests.cc.

2990  {
2991  Rect r = Rect::MakeXYWH(100, 200, 300, 400);
2992  auto points = r.GetTransformedPoints(Matrix::MakeTranslation({10, 20}));
2993  EXPECT_POINT_NEAR(points[0], Point(110, 220));
2994  EXPECT_POINT_NEAR(points[1], Point(410, 220));
2995  EXPECT_POINT_NEAR(points[2], Point(110, 620));
2996  EXPECT_POINT_NEAR(points[3], Point(410, 620));
2997 }

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

◆ TEST() [313/465]

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

Definition at line 1617 of file rect_unittests.cc.

1617  {
1618  auto check_nans = [](const Rect& a, const Rect& b, const std::string& label) {
1619  ASSERT_TRUE(a.IsFinite()) << label;
1620  ASSERT_TRUE(b.IsFinite()) << label;
1621 
1622  for (int i = 1; i < 16; i++) {
1623  // NaN in a produces empty
1624  EXPECT_FALSE(swap_nan(a, i).Intersection(b).has_value())
1625  << label << ", index = " << i;
1626  // NaN in b produces empty
1627  EXPECT_FALSE(a.Intersection(swap_nan(b, i)).has_value())
1628  << label << ", index = " << i;
1629  // NaN in both is empty
1630  for (int j = 1; j < 16; j++) {
1631  EXPECT_FALSE(swap_nan(a, i).Intersection(swap_nan(b, j)).has_value())
1632  << label << ", indices = " << i << ", " << j;
1633  }
1634  }
1635  };
1636 
1637  auto check_empty_flips = [](const Rect& a, const Rect& b,
1638  const std::string& label) {
1639  ASSERT_FALSE(a.IsEmpty());
1640  // b is allowed to be empty
1641 
1642  // unflipped a vs flipped (empty) b yields a
1643  EXPECT_FALSE(a.Intersection(flip_lr(b)).has_value()) << label;
1644  EXPECT_TRUE(a.IntersectionOrEmpty(flip_lr(b)).IsEmpty()) << label;
1645  EXPECT_FALSE(a.Intersection(flip_tb(b)).has_value()) << label;
1646  EXPECT_TRUE(a.IntersectionOrEmpty(flip_tb(b)).IsEmpty()) << label;
1647  EXPECT_FALSE(a.Intersection(flip_lrtb(b)).has_value()) << label;
1648  EXPECT_TRUE(a.IntersectionOrEmpty(flip_lrtb(b)).IsEmpty()) << label;
1649 
1650  // flipped (empty) a vs unflipped b yields b
1651  EXPECT_FALSE(flip_lr(a).Intersection(b).has_value()) << label;
1652  EXPECT_TRUE(flip_lr(a).IntersectionOrEmpty(b).IsEmpty()) << label;
1653  EXPECT_FALSE(flip_tb(a).Intersection(b).has_value()) << label;
1654  EXPECT_TRUE(flip_tb(a).IntersectionOrEmpty(b).IsEmpty()) << label;
1655  EXPECT_FALSE(flip_lrtb(a).Intersection(b).has_value()) << label;
1656  EXPECT_TRUE(flip_lrtb(a).IntersectionOrEmpty(b).IsEmpty()) << label;
1657 
1658  // flipped (empty) a vs flipped (empty) b yields empty
1659  EXPECT_FALSE(flip_lr(a).Intersection(flip_lr(b)).has_value()) << label;
1660  EXPECT_TRUE(flip_lr(a).IntersectionOrEmpty(flip_lr(b)).IsEmpty()) << label;
1661  EXPECT_FALSE(flip_tb(a).Intersection(flip_tb(b)).has_value()) << label;
1662  EXPECT_TRUE(flip_tb(a).IntersectionOrEmpty(flip_tb(b)).IsEmpty()) << label;
1663  EXPECT_FALSE(flip_lrtb(a).Intersection(flip_lrtb(b)).has_value()) << label;
1664  EXPECT_TRUE(flip_lrtb(a).IntersectionOrEmpty(flip_lrtb(b)).IsEmpty())
1665  << label;
1666  };
1667 
1668  auto test_non_empty = [&check_nans, &check_empty_flips](
1669  const Rect& a, const Rect& b, const Rect& result) {
1670  ASSERT_FALSE(a.IsEmpty()) << a;
1671  // b is allowed to be empty
1672 
1673  std::stringstream stream;
1674  stream << a << " union " << b;
1675  auto label = stream.str();
1676 
1677  EXPECT_TRUE(a.Intersection(b).has_value()) << label;
1678  EXPECT_TRUE(b.Intersection(a).has_value()) << label;
1679  EXPECT_EQ(a.Intersection(b), result) << label;
1680  EXPECT_EQ(b.Intersection(a), result) << label;
1681  check_empty_flips(a, b, label);
1682  check_nans(a, b, label);
1683  };
1684 
1685  auto test_empty = [&check_nans, &check_empty_flips](const Rect& a,
1686  const Rect& b) {
1687  ASSERT_FALSE(a.IsEmpty()) << a;
1688  // b is allowed to be empty
1689 
1690  std::stringstream stream;
1691  stream << a << " union " << b;
1692  auto label = stream.str();
1693 
1694  EXPECT_FALSE(a.Intersection(b).has_value()) << label;
1695  EXPECT_TRUE(a.IntersectionOrEmpty(b).IsEmpty()) << label;
1696  EXPECT_FALSE(b.Intersection(a).has_value()) << label;
1697  EXPECT_TRUE(b.IntersectionOrEmpty(a).IsEmpty()) << label;
1698  check_empty_flips(a, b, label);
1699  check_nans(a, b, label);
1700  };
1701 
1702  {
1703  auto a = Rect::MakeXYWH(100, 100, 100, 100);
1704  auto b = Rect::MakeXYWH(0, 0, 0, 0);
1705 
1706  test_empty(a, b);
1707  }
1708 
1709  {
1710  auto a = Rect::MakeXYWH(100, 100, 100, 100);
1711  auto b = Rect::MakeXYWH(10, 10, 0, 0);
1712 
1713  test_empty(a, b);
1714  }
1715 
1716  {
1717  auto a = Rect::MakeXYWH(0, 0, 100, 100);
1718  auto b = Rect::MakeXYWH(10, 10, 100, 100);
1719  auto expected = Rect::MakeXYWH(10, 10, 90, 90);
1720 
1721  test_non_empty(a, b, expected);
1722  }
1723 
1724  {
1725  auto a = Rect::MakeXYWH(0, 0, 100, 100);
1726  auto b = Rect::MakeXYWH(100, 100, 100, 100);
1727 
1728  test_empty(a, b);
1729  }
1730 
1731  {
1732  auto a = Rect::MakeMaximum();
1733  auto b = Rect::MakeXYWH(10, 10, 300, 300);
1734 
1735  test_non_empty(a, b, b);
1736  }
1737 
1738  {
1739  auto a = Rect::MakeMaximum();
1740  auto b = Rect::MakeMaximum();
1741 
1742  test_non_empty(a, b, Rect::MakeMaximum());
1743  }
1744 }

References impeller::saturated::b, flip_lr(), flip_lrtb(), flip_tb(), impeller::TRect< T >::Intersection(), impeller::TRect< T >::IntersectionOrEmpty(), impeller::TRect< T >::IsEmpty(), impeller::TRect< T >::IsFinite(), impeller::TRect< Scalar >::MakeMaximum(), impeller::TRect< Scalar >::MakeXYWH(), and swap_nan().

◆ TEST() [314/465]

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

Definition at line 1951 of file rect_unittests.cc.

1951  {
1952  auto check_nans = [](const Rect& a, const Rect& b, const std::string& label) {
1953  ASSERT_TRUE(a.IsFinite()) << label;
1954  ASSERT_TRUE(b.IsFinite()) << label;
1955 
1956  for (int i = 1; i < 16; i++) {
1957  // NaN in a produces b
1958  EXPECT_FALSE(swap_nan(a, i).IntersectsWithRect(b))
1959  << label << ", index = " << i;
1960  // NaN in b produces a
1961  EXPECT_FALSE(a.IntersectsWithRect(swap_nan(b, i)))
1962  << label << ", index = " << i;
1963  // NaN in both is empty
1964  for (int j = 1; j < 16; j++) {
1965  EXPECT_FALSE(swap_nan(a, i).IntersectsWithRect(swap_nan(b, j)))
1966  << label << ", indices = " << i << ", " << j;
1967  }
1968  }
1969  };
1970 
1971  auto check_empty_flips = [](const Rect& a, const Rect& b,
1972  const std::string& label) {
1973  ASSERT_FALSE(a.IsEmpty());
1974  // b is allowed to be empty
1975 
1976  // unflipped a vs flipped (empty) b yields a
1977  EXPECT_FALSE(a.IntersectsWithRect(flip_lr(b))) << label;
1978  EXPECT_FALSE(a.IntersectsWithRect(flip_tb(b))) << label;
1979  EXPECT_FALSE(a.IntersectsWithRect(flip_lrtb(b))) << label;
1980 
1981  // flipped (empty) a vs unflipped b yields b
1982  EXPECT_FALSE(flip_lr(a).IntersectsWithRect(b)) << label;
1983  EXPECT_FALSE(flip_tb(a).IntersectsWithRect(b)) << label;
1984  EXPECT_FALSE(flip_lrtb(a).IntersectsWithRect(b)) << label;
1985 
1986  // flipped (empty) a vs flipped (empty) b yields empty
1987  EXPECT_FALSE(flip_lr(a).IntersectsWithRect(flip_lr(b))) << label;
1988  EXPECT_FALSE(flip_tb(a).IntersectsWithRect(flip_tb(b))) << label;
1989  EXPECT_FALSE(flip_lrtb(a).IntersectsWithRect(flip_lrtb(b))) << label;
1990  };
1991 
1992  auto test_non_empty = [&check_nans, &check_empty_flips](const Rect& a,
1993  const Rect& b) {
1994  ASSERT_FALSE(a.IsEmpty()) << a;
1995  // b is allowed to be empty
1996 
1997  std::stringstream stream;
1998  stream << a << " union " << b;
1999  auto label = stream.str();
2000 
2001  EXPECT_TRUE(a.IntersectsWithRect(b)) << label;
2002  EXPECT_TRUE(b.IntersectsWithRect(a)) << label;
2003  check_empty_flips(a, b, label);
2004  check_nans(a, b, label);
2005  };
2006 
2007  auto test_empty = [&check_nans, &check_empty_flips](const Rect& a,
2008  const Rect& b) {
2009  ASSERT_FALSE(a.IsEmpty()) << a;
2010  // b is allowed to be empty
2011 
2012  std::stringstream stream;
2013  stream << a << " union " << b;
2014  auto label = stream.str();
2015 
2016  EXPECT_FALSE(a.IntersectsWithRect(b)) << label;
2017  EXPECT_FALSE(b.IntersectsWithRect(a)) << label;
2018  check_empty_flips(a, b, label);
2019  check_nans(a, b, label);
2020  };
2021 
2022  {
2023  auto a = Rect::MakeXYWH(100, 100, 100, 100);
2024  auto b = Rect::MakeXYWH(0, 0, 0, 0);
2025 
2026  test_empty(a, b);
2027  }
2028 
2029  {
2030  auto a = Rect::MakeXYWH(100, 100, 100, 100);
2031  auto b = Rect::MakeXYWH(10, 10, 0, 0);
2032 
2033  test_empty(a, b);
2034  }
2035 
2036  {
2037  auto a = Rect::MakeXYWH(0, 0, 100, 100);
2038  auto b = Rect::MakeXYWH(10, 10, 100, 100);
2039 
2040  test_non_empty(a, b);
2041  }
2042 
2043  {
2044  auto a = Rect::MakeXYWH(0, 0, 100, 100);
2045  auto b = Rect::MakeXYWH(100, 100, 100, 100);
2046 
2047  test_empty(a, b);
2048  }
2049 
2050  {
2051  auto a = Rect::MakeMaximum();
2052  auto b = Rect::MakeXYWH(10, 10, 100, 100);
2053 
2054  test_non_empty(a, b);
2055  }
2056 
2057  {
2058  auto a = Rect::MakeMaximum();
2059  auto b = Rect::MakeMaximum();
2060 
2061  test_non_empty(a, b);
2062  }
2063 }

References impeller::saturated::b, flip_lr(), flip_lrtb(), flip_tb(), impeller::TRect< T >::IntersectsWithRect(), impeller::TRect< T >::IsEmpty(), impeller::TRect< T >::IsFinite(), impeller::TRect< Scalar >::MakeMaximum(), impeller::TRect< Scalar >::MakeXYWH(), and swap_nan().

◆ TEST() [315/465]

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

Definition at line 620 of file rect_unittests.cc.

620  {
621  Rect rect = Rect::MakeMaximum();
622  auto inf = std::numeric_limits<Scalar>::infinity();
623  auto min = std::numeric_limits<Scalar>::lowest();
624  auto max = std::numeric_limits<Scalar>::max();
625 
626  EXPECT_EQ(rect.GetLeft(), min);
627  EXPECT_EQ(rect.GetTop(), min);
628  EXPECT_EQ(rect.GetRight(), max);
629  EXPECT_EQ(rect.GetBottom(), max);
630  EXPECT_EQ(rect.GetX(), min);
631  EXPECT_EQ(rect.GetY(), min);
632  EXPECT_EQ(rect.GetWidth(), inf);
633  EXPECT_EQ(rect.GetHeight(), inf);
634  EXPECT_FALSE(rect.IsEmpty());
635  EXPECT_TRUE(rect.IsFinite());
636 }

References impeller::TRect< T >::GetBottom(), impeller::TRect< T >::GetHeight(), impeller::TRect< T >::GetLeft(), impeller::TRect< T >::GetRight(), impeller::TRect< T >::GetTop(), impeller::TRect< T >::GetWidth(), impeller::TRect< T >::GetX(), impeller::TRect< T >::GetY(), impeller::TRect< T >::IsEmpty(), impeller::TRect< T >::IsFinite(), and impeller::TRect< Scalar >::MakeMaximum().

◆ TEST() [316/465]

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

Definition at line 2999 of file rect_unittests.cc.

2999  {
3000  {
3001  std::vector<Point> points{{1, 5}, {4, -1}, {0, 6}};
3002  auto r = Rect::MakePointBounds(points.begin(), points.end());
3003  auto expected = Rect::MakeXYWH(0, -1, 4, 7);
3004  EXPECT_TRUE(r.has_value());
3005  if (r.has_value()) {
3006  EXPECT_RECT_NEAR(r.value(), expected);
3007  }
3008  }
3009  {
3010  std::vector<Point> points;
3011  std::optional<Rect> r = Rect::MakePointBounds(points.begin(), points.end());
3012  EXPECT_FALSE(r.has_value());
3013  }
3014 }

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

◆ TEST() [317/465]

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

Definition at line 590 of file rect_unittests.cc.

590  {
591  {
592  Size s(100, 200);
593  Rect r = Rect::MakeSize(s);
594  Rect expected = Rect::MakeLTRB(0, 0, 100, 200);
595  EXPECT_RECT_NEAR(r, expected);
596  }
597 
598  {
599  ISize s(100, 200);
600  Rect r = Rect::MakeSize(s);
601  Rect expected = Rect::MakeLTRB(0, 0, 100, 200);
602  EXPECT_RECT_NEAR(r, expected);
603  }
604 
605  {
606  Size s(100, 200);
607  IRect r = IRect::MakeSize(s);
608  IRect expected = IRect::MakeLTRB(0, 0, 100, 200);
609  EXPECT_EQ(r, expected);
610  }
611 
612  {
613  ISize s(100, 200);
614  IRect r = IRect::MakeSize(s);
615  IRect expected = IRect::MakeLTRB(0, 0, 100, 200);
616  EXPECT_EQ(r, expected);
617  }
618 }

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

◆ TEST() [318/465]

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

Definition at line 702 of file rect_unittests.cc.

702  {
703  {
704  Rect r = Rect::MakeOriginSize({10, 20}, {50, 40});
705  EXPECT_EQ(r.GetOrigin(), Point(10, 20));
706  EXPECT_EQ(r.GetSize(), Size(50, 40));
707  EXPECT_EQ(r.GetX(), 10);
708  EXPECT_EQ(r.GetY(), 20);
709  EXPECT_EQ(r.GetWidth(), 50);
710  EXPECT_EQ(r.GetHeight(), 40);
711  auto expected_array = std::array<Scalar, 4>{10, 20, 50, 40};
712  EXPECT_EQ(r.GetXYWH(), expected_array);
713  }
714 
715  {
716  Rect r = Rect::MakeLTRB(10, 20, 50, 40);
717  EXPECT_EQ(r.GetOrigin(), Point(10, 20));
718  EXPECT_EQ(r.GetSize(), Size(40, 20));
719  EXPECT_EQ(r.GetX(), 10);
720  EXPECT_EQ(r.GetY(), 20);
721  EXPECT_EQ(r.GetWidth(), 40);
722  EXPECT_EQ(r.GetHeight(), 20);
723  auto expected_array = std::array<Scalar, 4>{10, 20, 40, 20};
724  EXPECT_EQ(r.GetXYWH(), expected_array);
725  }
726 }

References impeller::TRect< T >::GetHeight(), impeller::TRect< T >::GetOrigin(), impeller::TRect< T >::GetSize(), impeller::TRect< T >::GetWidth(), impeller::TRect< T >::GetX(), impeller::TRect< T >::GetXYWH(), impeller::TRect< T >::GetY(), impeller::TRect< Scalar >::MakeLTRB(), and impeller::TRect< Scalar >::MakeOriginSize().

◆ TEST() [319/465]

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

Definition at line 384 of file rect_unittests.cc.

384  {
385  auto min = std::numeric_limits<Scalar>::lowest();
386  auto max = std::numeric_limits<Scalar>::max();
387  auto inf = std::numeric_limits<Scalar>::infinity();
388 
389  // 8 cases:
390  // finite negative X, max W
391  // ~min X, ~max W
392  // finite negative Y, max H
393  // ~min Y, ~max H
394  // finite positive X, min W
395  // ~min X, ~min W
396  // finite positive Y, min H
397  // ~min Y, ~min H
398 
399  // a small finite value subtracted from a max value will remain max
400  // a very large finite value (like min) subtracted from max will go to inf
401 
402  {
403  Rect rect = Rect::MakeLTRB(-5.0f, 10.0f, max, 25.0f);
404 
405  EXPECT_EQ(rect.GetLeft(), -5.0f);
406  EXPECT_EQ(rect.GetTop(), 10.0f);
407  EXPECT_EQ(rect.GetRight(), max);
408  EXPECT_EQ(rect.GetBottom(), 25.0f);
409  EXPECT_EQ(rect.GetX(), -5.0f);
410  EXPECT_EQ(rect.GetY(), 10.0f);
411  EXPECT_EQ(rect.GetWidth(), max);
412  EXPECT_EQ(rect.GetHeight(), 15.0f);
413  EXPECT_FALSE(rect.IsEmpty());
414  EXPECT_TRUE(rect.IsFinite());
415  }
416 
417  {
418  Rect rect = Rect::MakeLTRB(min + 5.0f, 10.0f, max - 5.0f, 25.0f);
419 
420  EXPECT_EQ(rect.GetLeft(), min + 5.0f);
421  EXPECT_EQ(rect.GetTop(), 10.0f);
422  EXPECT_EQ(rect.GetRight(), max - 5.0f);
423  EXPECT_EQ(rect.GetBottom(), 25.0f);
424  EXPECT_EQ(rect.GetX(), min + 5.0f);
425  EXPECT_EQ(rect.GetY(), 10.0f);
426  EXPECT_EQ(rect.GetWidth(), inf);
427  EXPECT_EQ(rect.GetHeight(), 15.0f);
428  EXPECT_FALSE(rect.IsEmpty());
429  EXPECT_TRUE(rect.IsFinite());
430  }
431 
432  {
433  Rect rect = Rect::MakeLTRB(5.0f, -10.0f, 20.0f, max);
434 
435  EXPECT_EQ(rect.GetLeft(), 5.0f);
436  EXPECT_EQ(rect.GetTop(), -10.0f);
437  EXPECT_EQ(rect.GetRight(), 20.0f);
438  EXPECT_EQ(rect.GetBottom(), max);
439  EXPECT_EQ(rect.GetX(), 5.0f);
440  EXPECT_EQ(rect.GetY(), -10.0f);
441  EXPECT_EQ(rect.GetWidth(), 15.0f);
442  EXPECT_EQ(rect.GetHeight(), max);
443  EXPECT_FALSE(rect.IsEmpty());
444  EXPECT_TRUE(rect.IsFinite());
445  }
446 
447  {
448  Rect rect = Rect::MakeLTRB(5.0f, min + 10.0f, 20.0f, max - 15.0f);
449 
450  EXPECT_EQ(rect.GetLeft(), 5.0f);
451  EXPECT_EQ(rect.GetTop(), min + 10.0f);
452  EXPECT_EQ(rect.GetRight(), 20.0f);
453  EXPECT_EQ(rect.GetBottom(), max - 15.0f);
454  EXPECT_EQ(rect.GetX(), 5.0f);
455  EXPECT_EQ(rect.GetY(), min + 10.0f);
456  EXPECT_EQ(rect.GetWidth(), 15.0f);
457  EXPECT_EQ(rect.GetHeight(), inf);
458  EXPECT_FALSE(rect.IsEmpty());
459  EXPECT_TRUE(rect.IsFinite());
460  }
461 
462  {
463  Rect rect = Rect::MakeLTRB(5.0f, 10.0f, min, 25.0f);
464 
465  EXPECT_EQ(rect.GetLeft(), 5.0f);
466  EXPECT_EQ(rect.GetTop(), 10.0f);
467  EXPECT_EQ(rect.GetRight(), min);
468  EXPECT_EQ(rect.GetBottom(), 25.0f);
469  EXPECT_EQ(rect.GetX(), 5.0f);
470  EXPECT_EQ(rect.GetY(), 10.0f);
471  EXPECT_EQ(rect.GetWidth(), min);
472  EXPECT_EQ(rect.GetHeight(), 15.0f);
473  EXPECT_TRUE(rect.IsEmpty());
474  EXPECT_TRUE(rect.IsFinite());
475  }
476 
477  {
478  Rect rect = Rect::MakeLTRB(max - 5.0f, 10.0f, min + 10.0f, 25.0f);
479 
480  EXPECT_EQ(rect.GetLeft(), max - 5.0f);
481  EXPECT_EQ(rect.GetTop(), 10.0f);
482  EXPECT_EQ(rect.GetRight(), min + 10.0f);
483  EXPECT_EQ(rect.GetBottom(), 25.0f);
484  EXPECT_EQ(rect.GetX(), max - 5.0f);
485  EXPECT_EQ(rect.GetY(), 10.0f);
486  EXPECT_EQ(rect.GetWidth(), -inf);
487  EXPECT_EQ(rect.GetHeight(), 15.0f);
488  EXPECT_TRUE(rect.IsEmpty());
489  EXPECT_TRUE(rect.IsFinite());
490  }
491 
492  {
493  Rect rect = Rect::MakeLTRB(5.0f, 10.0f, 20.0f, min);
494 
495  EXPECT_EQ(rect.GetLeft(), 5.0f);
496  EXPECT_EQ(rect.GetTop(), 10.0f);
497  EXPECT_EQ(rect.GetRight(), 20.0f);
498  EXPECT_EQ(rect.GetBottom(), min);
499  EXPECT_EQ(rect.GetX(), 5.0f);
500  EXPECT_EQ(rect.GetY(), 10.0f);
501  EXPECT_EQ(rect.GetWidth(), 15.0f);
502  EXPECT_EQ(rect.GetHeight(), min);
503  EXPECT_TRUE(rect.IsEmpty());
504  EXPECT_TRUE(rect.IsFinite());
505  }
506 
507  {
508  Rect rect = Rect::MakeLTRB(5.0f, max - 5.0f, 20.0f, min + 10.0f);
509 
510  EXPECT_EQ(rect.GetLeft(), 5.0f);
511  EXPECT_EQ(rect.GetTop(), max - 5.0f);
512  EXPECT_EQ(rect.GetRight(), 20.0f);
513  EXPECT_EQ(rect.GetBottom(), min + 10.0f);
514  EXPECT_EQ(rect.GetX(), 5.0f);
515  EXPECT_EQ(rect.GetY(), max - 5.0f);
516  EXPECT_EQ(rect.GetWidth(), 15.0f);
517  EXPECT_EQ(rect.GetHeight(), -inf);
518  EXPECT_TRUE(rect.IsEmpty());
519  EXPECT_TRUE(rect.IsFinite());
520  }
521 }

References impeller::TRect< T >::GetBottom(), impeller::TRect< T >::GetHeight(), impeller::TRect< T >::GetLeft(), impeller::TRect< T >::GetRight(), impeller::TRect< T >::GetTop(), impeller::TRect< T >::GetWidth(), impeller::TRect< T >::GetX(), impeller::TRect< T >::GetY(), impeller::TRect< T >::IsEmpty(), impeller::TRect< T >::IsFinite(), and impeller::TRect< Scalar >::MakeLTRB().

◆ TEST() [320/465]

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

Definition at line 178 of file rect_unittests.cc.

178  {
179  auto min = std::numeric_limits<Scalar>::lowest();
180  auto max = std::numeric_limits<Scalar>::max();
181  auto inf = std::numeric_limits<Scalar>::infinity();
182 
183  // 8 cases:
184  // finite X, max W
185  // max X, max W
186  // finite Y, max H
187  // max Y, max H
188  // finite X, min W
189  // min X, min W
190  // finite Y, min H
191  // min Y, min H
192 
193  // a small finite value added to a max value will remain max
194  // a very large finite value (like max) added to max will go to infinity
195 
196  {
197  Rect rect = Rect::MakeXYWH(5.0, 10.0f, max, 15.0f);
198 
199  EXPECT_EQ(rect.GetLeft(), 5.0f);
200  EXPECT_EQ(rect.GetTop(), 10.0f);
201  EXPECT_EQ(rect.GetRight(), max);
202  EXPECT_EQ(rect.GetBottom(), 25.0f);
203  EXPECT_EQ(rect.GetX(), 5.0f);
204  EXPECT_EQ(rect.GetY(), 10.0f);
205  EXPECT_EQ(rect.GetWidth(), max);
206  EXPECT_EQ(rect.GetHeight(), 15.0f);
207  EXPECT_FALSE(rect.IsEmpty());
208  EXPECT_TRUE(rect.IsFinite());
209  }
210 
211  {
212  Rect rect = Rect::MakeXYWH(max, 10.0f, max, 15.0f);
213 
214  EXPECT_EQ(rect.GetLeft(), max);
215  EXPECT_EQ(rect.GetTop(), 10.0f);
216  EXPECT_EQ(rect.GetRight(), inf);
217  EXPECT_EQ(rect.GetBottom(), 25.0f);
218  EXPECT_EQ(rect.GetX(), max);
219  EXPECT_EQ(rect.GetY(), 10.0f);
220  EXPECT_EQ(rect.GetWidth(), inf);
221  EXPECT_EQ(rect.GetHeight(), 15.0f);
222  EXPECT_FALSE(rect.IsEmpty());
223  EXPECT_FALSE(rect.IsFinite());
224  }
225 
226  {
227  Rect rect = Rect::MakeXYWH(5.0f, 10.0f, 20.0f, max);
228 
229  EXPECT_EQ(rect.GetLeft(), 5.0f);
230  EXPECT_EQ(rect.GetTop(), 10.0f);
231  EXPECT_EQ(rect.GetRight(), 25.0f);
232  EXPECT_EQ(rect.GetBottom(), max);
233  EXPECT_EQ(rect.GetX(), 5.0f);
234  EXPECT_EQ(rect.GetY(), 10.0f);
235  EXPECT_EQ(rect.GetWidth(), 20.0f);
236  EXPECT_EQ(rect.GetHeight(), max);
237  EXPECT_FALSE(rect.IsEmpty());
238  EXPECT_TRUE(rect.IsFinite());
239  }
240 
241  {
242  Rect rect = Rect::MakeXYWH(5.0f, max, 20.0f, max);
243 
244  EXPECT_EQ(rect.GetLeft(), 5.0f);
245  EXPECT_EQ(rect.GetTop(), max);
246  EXPECT_EQ(rect.GetRight(), 25.0f);
247  EXPECT_EQ(rect.GetBottom(), inf);
248  EXPECT_EQ(rect.GetX(), 5.0f);
249  EXPECT_EQ(rect.GetY(), max);
250  EXPECT_EQ(rect.GetWidth(), 20.0f);
251  EXPECT_EQ(rect.GetHeight(), inf);
252  EXPECT_FALSE(rect.IsEmpty());
253  EXPECT_FALSE(rect.IsFinite());
254  }
255 
256  {
257  Rect rect = Rect::MakeXYWH(5.0, 10.0f, min, 15.0f);
258 
259  EXPECT_EQ(rect.GetLeft(), 5.0f);
260  EXPECT_EQ(rect.GetTop(), 10.0f);
261  EXPECT_EQ(rect.GetRight(), min);
262  EXPECT_EQ(rect.GetBottom(), 25.0f);
263  EXPECT_EQ(rect.GetX(), 5.0f);
264  EXPECT_EQ(rect.GetY(), 10.0f);
265  EXPECT_EQ(rect.GetWidth(), min);
266  EXPECT_EQ(rect.GetHeight(), 15.0f);
267  EXPECT_TRUE(rect.IsEmpty());
268  EXPECT_TRUE(rect.IsFinite());
269  }
270 
271  {
272  Rect rect = Rect::MakeXYWH(min, 10.0f, min, 15.0f);
273 
274  EXPECT_EQ(rect.GetLeft(), min);
275  EXPECT_EQ(rect.GetTop(), 10.0f);
276  EXPECT_EQ(rect.GetRight(), -inf);
277  EXPECT_EQ(rect.GetBottom(), 25.0f);
278  EXPECT_EQ(rect.GetX(), min);
279  EXPECT_EQ(rect.GetY(), 10.0f);
280  EXPECT_EQ(rect.GetWidth(), -inf);
281  EXPECT_EQ(rect.GetHeight(), 15.0f);
282  EXPECT_TRUE(rect.IsEmpty());
283  EXPECT_FALSE(rect.IsFinite());
284  }
285 
286  {
287  Rect rect = Rect::MakeXYWH(5.0f, 10.0f, 20.0f, min);
288 
289  EXPECT_EQ(rect.GetLeft(), 5.0f);
290  EXPECT_EQ(rect.GetTop(), 10.0f);
291  EXPECT_EQ(rect.GetRight(), 25.0f);
292  EXPECT_EQ(rect.GetBottom(), min);
293  EXPECT_EQ(rect.GetX(), 5.0f);
294  EXPECT_EQ(rect.GetY(), 10.0f);
295  EXPECT_EQ(rect.GetWidth(), 20.0f);
296  EXPECT_EQ(rect.GetHeight(), min);
297  EXPECT_TRUE(rect.IsEmpty());
298  EXPECT_TRUE(rect.IsFinite());
299  }
300 
301  {
302  Rect rect = Rect::MakeXYWH(5.0f, min, 20.0f, min);
303 
304  EXPECT_EQ(rect.GetLeft(), 5.0f);
305  EXPECT_EQ(rect.GetTop(), min);
306  EXPECT_EQ(rect.GetRight(), 25.0f);
307  EXPECT_EQ(rect.GetBottom(), -inf);
308  EXPECT_EQ(rect.GetX(), 5.0f);
309  EXPECT_EQ(rect.GetY(), min);
310  EXPECT_EQ(rect.GetWidth(), 20.0f);
311  EXPECT_EQ(rect.GetHeight(), -inf);
312  EXPECT_TRUE(rect.IsEmpty());
313  EXPECT_FALSE(rect.IsFinite());
314  }
315 }

References impeller::TRect< T >::GetBottom(), impeller::TRect< T >::GetHeight(), impeller::TRect< T >::GetLeft(), impeller::TRect< T >::GetRight(), impeller::TRect< T >::GetTop(), impeller::TRect< T >::GetWidth(), impeller::TRect< T >::GetX(), impeller::TRect< T >::GetY(), impeller::TRect< T >::IsEmpty(), impeller::TRect< T >::IsFinite(), and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST() [321/465]

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

Definition at line 3044 of file rect_unittests.cc.

3044  {
3045  {
3046  auto r = Rect::MakeLTRB(-100, -100, 100, 100);
3047  auto actual = r.Project(r);
3048  auto expected = Rect::MakeLTRB(0, 0, 1, 1);
3049  EXPECT_RECT_NEAR(expected, actual);
3050  }
3051  {
3052  auto r = Rect::MakeLTRB(-100, -100, 100, 100);
3053  auto actual = r.Project(Rect::MakeLTRB(0, 0, 100, 100));
3054  auto expected = Rect::MakeLTRB(0.5, 0.5, 1, 1);
3055  EXPECT_RECT_NEAR(expected, actual);
3056  }
3057 }

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

◆ TEST() [322/465]

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

Definition at line 3083 of file rect_unittests.cc.

3083  {
3084  {
3085  auto r = Rect::MakeLTRB(-100, -200, 300, 400);
3086  EXPECT_EQ(Rect::Round(r), r);
3087  }
3088  {
3089  auto r = Rect::MakeLTRB(-100.4, -200.4, 300.4, 400.4);
3090  EXPECT_EQ(Rect::Round(r), Rect::MakeLTRB(-100, -200, 300, 400));
3091  }
3092  {
3093  auto r = Rect::MakeLTRB(-100.5, -200.5, 300.5, 400.5);
3094  EXPECT_EQ(Rect::Round(r), Rect::MakeLTRB(-101, -201, 301, 401));
3095  }
3096 }

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

◆ TEST() [323/465]

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

Definition at line 3059 of file rect_unittests.cc.

3059  {
3060  {
3061  auto r = Rect::MakeLTRB(-100, -200, 300, 400);
3062  EXPECT_EQ(Rect::RoundOut(r), r);
3063  }
3064  {
3065  auto r = Rect::MakeLTRB(-100.1, -200.1, 300.1, 400.1);
3066  EXPECT_EQ(Rect::RoundOut(r), Rect::MakeLTRB(-101, -201, 301, 401));
3067  }
3068 }

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

◆ TEST() [324/465]

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

Definition at line 754 of file rect_unittests.cc.

754  {
755  Rect rect;
756 
757  EXPECT_EQ(Rect::RoundOut(rect), Rect());
758 
759  EXPECT_EQ(IRect::RoundOut(rect), IRect());
760 }

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

◆ TEST() [325/465]

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

Definition at line 762 of file rect_unittests.cc.

762  {
763  Rect rect = Rect::MakeLTRB(5.125f, 10.75f, 20.625f, 25.375f);
764 
765  EXPECT_EQ(Rect::RoundOut(rect), Rect::MakeLTRB(5.0f, 10.0f, 21.0f, 26.0f));
766 
767  EXPECT_EQ(IRect::RoundOut(rect), IRect::MakeLTRB(5, 10, 21, 26));
768 }

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

◆ TEST() [326/465]

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

Definition at line 770 of file rect_unittests.cc.

770  {
771  auto test = [](int corners) {
772  EXPECT_TRUE(corners >= 0 && corners <= 0xf);
773  Scalar l, t, r, b;
774  int64_t il, it, ir, ib;
775  l = il = 50;
776  t = it = 50;
777  r = ir = 80;
778  b = ib = 80;
779  if ((corners & (1 << 0)) != 0) {
780  l = -1E20;
781  il = std::numeric_limits<int64_t>::min();
782  }
783  if ((corners & (1 << 1)) != 0) {
784  t = -1E20;
785  it = std::numeric_limits<int64_t>::min();
786  }
787  if ((corners & (1 << 2)) != 0) {
788  r = +1E20;
789  ir = std::numeric_limits<int64_t>::max();
790  }
791  if ((corners & (1 << 3)) != 0) {
792  b = +1E20;
793  ib = std::numeric_limits<int64_t>::max();
794  }
795 
796  Rect rect = Rect::MakeLTRB(l, t, r, b);
797  IRect irect = IRect::RoundOut(rect);
798  EXPECT_EQ(irect.GetLeft(), il) << corners;
799  EXPECT_EQ(irect.GetTop(), it) << corners;
800  EXPECT_EQ(irect.GetRight(), ir) << corners;
801  EXPECT_EQ(irect.GetBottom(), ib) << corners;
802  };
803 
804  for (int corners = 0; corners <= 15; corners++) {
805  test(corners);
806  }
807 }

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

◆ TEST() [327/465]

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

Definition at line 929 of file rect_unittests.cc.

929  {
930  auto test1 = [](Rect rect, Scalar scale) {
931  Rect expected = Rect::MakeXYWH(rect.GetX() * scale, //
932  rect.GetY() * scale, //
933  rect.GetWidth() * scale, //
934  rect.GetHeight() * scale);
935 
936  EXPECT_RECT_NEAR(rect.Scale(scale), expected) //
937  << rect << " * " << scale;
938  EXPECT_RECT_NEAR(rect.Scale(scale, scale), expected) //
939  << rect << " * " << scale;
940  EXPECT_RECT_NEAR(rect.Scale(Point(scale, scale)), expected) //
941  << rect << " * " << scale;
942  EXPECT_RECT_NEAR(rect.Scale(Size(scale, scale)), expected) //
943  << rect << " * " << scale;
944  };
945 
946  auto test2 = [&test1](Rect rect, Scalar scale_x, Scalar scale_y) {
947  Rect expected = Rect::MakeXYWH(rect.GetX() * scale_x, //
948  rect.GetY() * scale_y, //
949  rect.GetWidth() * scale_x, //
950  rect.GetHeight() * scale_y);
951 
952  EXPECT_RECT_NEAR(rect.Scale(scale_x, scale_y), expected) //
953  << rect << " * " << scale_x << ", " << scale_y;
954  EXPECT_RECT_NEAR(rect.Scale(Point(scale_x, scale_y)), expected) //
955  << rect << " * " << scale_x << ", " << scale_y;
956  EXPECT_RECT_NEAR(rect.Scale(Size(scale_x, scale_y)), expected) //
957  << rect << " * " << scale_x << ", " << scale_y;
958 
959  test1(rect, scale_x);
960  test1(rect, scale_y);
961  };
962 
963  test2(Rect::MakeLTRB(10, 15, 100, 150), 1.0, 0.0);
964  test2(Rect::MakeLTRB(10, 15, 100, 150), 0.0, 1.0);
965  test2(Rect::MakeLTRB(10, 15, 100, 150), 0.0, 0.0);
966  test2(Rect::MakeLTRB(10, 15, 100, 150), 2.5, 3.5);
967  test2(Rect::MakeLTRB(10, 15, 100, 150), 3.5, 2.5);
968  test2(Rect::MakeLTRB(10, 15, -100, 150), 2.5, 3.5);
969  test2(Rect::MakeLTRB(10, 15, 100, -150), 2.5, 3.5);
970  test2(Rect::MakeLTRB(10, 15, 100, 150), -2.5, 3.5);
971  test2(Rect::MakeLTRB(10, 15, 100, 150), 2.5, -3.5);
972 }

References EXPECT_RECT_NEAR, impeller::TRect< T >::GetHeight(), impeller::TRect< T >::GetWidth(), impeller::TRect< T >::GetX(), impeller::TRect< T >::GetY(), impeller::TRect< Scalar >::MakeLTRB(), impeller::TRect< Scalar >::MakeXYWH(), scale, and impeller::TRect< T >::Scale().

◆ TEST() [328/465]

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

Definition at line 2983 of file rect_unittests.cc.

2983  {
2984  auto r = Rect::MakeLTRB(0, 0, 100, 100);
2985 
2986  EXPECT_EQ(r.Shift(Point(10, 5)), Rect::MakeLTRB(10, 5, 110, 105));
2987  EXPECT_EQ(r.Shift(Point(-10, -5)), Rect::MakeLTRB(-10, -5, 90, 95));
2988 }

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

◆ TEST() [329/465]

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

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

Definition at line 133 of file rect_unittests.cc.

133  {
134  // Using fractional-power-of-2 friendly values for equality tests
135  Rect rect = Rect::MakeWH(15.5f, 15.125f);
136 
137  EXPECT_EQ(rect.GetLeft(), 0.0f);
138  EXPECT_EQ(rect.GetTop(), 0.0f);
139  EXPECT_EQ(rect.GetRight(), 15.5f);
140  EXPECT_EQ(rect.GetBottom(), 15.125f);
141  EXPECT_EQ(rect.GetX(), 0.0f);
142  EXPECT_EQ(rect.GetY(), 0.0f);
143  EXPECT_EQ(rect.GetWidth(), 15.5f);
144  EXPECT_EQ(rect.GetHeight(), 15.125f);
145  EXPECT_FALSE(rect.IsEmpty());
146  EXPECT_TRUE(rect.IsFinite());
147 }

References impeller::TRect< T >::GetBottom(), impeller::TRect< T >::GetHeight(), impeller::TRect< T >::GetLeft(), impeller::TRect< T >::GetRight(), impeller::TRect< T >::GetTop(), impeller::TRect< T >::GetWidth(), impeller::TRect< T >::GetX(), impeller::TRect< T >::GetY(), impeller::TRect< T >::IsEmpty(), impeller::TRect< T >::IsFinite(), and impeller::TRect< Scalar >::MakeWH().

◆ TEST() [331/465]

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

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

Definition at line 1358 of file rect_unittests.cc.

1358  {
1359  auto check_nans = [](const Rect& a, const Rect& b, const std::string& label) {
1360  ASSERT_TRUE(a.IsFinite()) << label;
1361  ASSERT_TRUE(b.IsFinite()) << label;
1362  ASSERT_FALSE(a.Union(b).IsEmpty());
1363 
1364  for (int i = 1; i < 16; i++) {
1365  // NaN in a produces b
1366  EXPECT_EQ(swap_nan(a, i).Union(b), b) << label << ", index = " << i;
1367  // NaN in b produces a
1368  EXPECT_EQ(a.Union(swap_nan(b, i)), a) << label << ", index = " << i;
1369  // NaN in both is empty
1370  for (int j = 1; j < 16; j++) {
1371  EXPECT_TRUE(swap_nan(a, i).Union(swap_nan(b, j)).IsEmpty())
1372  << label << ", indices = " << i << ", " << j;
1373  }
1374  }
1375  };
1376 
1377  auto check_empty_flips = [](const Rect& a, const Rect& b,
1378  const std::string& label) {
1379  ASSERT_FALSE(a.IsEmpty());
1380  // b is allowed to be empty
1381 
1382  // unflipped a vs flipped (empty) b yields a
1383  EXPECT_EQ(a.Union(flip_lr(b)), a) << label;
1384  EXPECT_EQ(a.Union(flip_tb(b)), a) << label;
1385  EXPECT_EQ(a.Union(flip_lrtb(b)), a) << label;
1386 
1387  // flipped (empty) a vs unflipped b yields b
1388  EXPECT_EQ(flip_lr(a).Union(b), b) << label;
1389  EXPECT_EQ(flip_tb(a).Union(b), b) << label;
1390  EXPECT_EQ(flip_lrtb(a).Union(b), b) << label;
1391 
1392  // flipped (empty) a vs flipped (empty) b yields empty
1393  EXPECT_TRUE(flip_lr(a).Union(flip_lr(b)).IsEmpty()) << label;
1394  EXPECT_TRUE(flip_tb(a).Union(flip_tb(b)).IsEmpty()) << label;
1395  EXPECT_TRUE(flip_lrtb(a).Union(flip_lrtb(b)).IsEmpty()) << label;
1396  };
1397 
1398  auto test = [&check_nans, &check_empty_flips](const Rect& a, const Rect& b,
1399  const Rect& result) {
1400  ASSERT_FALSE(a.IsEmpty()) << a;
1401  // b is allowed to be empty
1402 
1403  std::stringstream stream;
1404  stream << a << " union " << b;
1405  auto label = stream.str();
1406 
1407  EXPECT_EQ(a.Union(b), result) << label;
1408  EXPECT_EQ(b.Union(a), result) << label;
1409  check_empty_flips(a, b, label);
1410  check_nans(a, b, label);
1411  };
1412 
1413  {
1414  auto a = Rect::MakeXYWH(100, 100, 100, 100);
1415  auto b = Rect::MakeXYWH(0, 0, 0, 0);
1416  auto expected = Rect::MakeXYWH(100, 100, 100, 100);
1417  test(a, b, expected);
1418  }
1419 
1420  {
1421  auto a = Rect::MakeXYWH(100, 100, 100, 100);
1422  auto b = Rect::MakeXYWH(0, 0, 1, 1);
1423  auto expected = Rect::MakeXYWH(0, 0, 200, 200);
1424  test(a, b, expected);
1425  }
1426 
1427  {
1428  auto a = Rect::MakeXYWH(100, 100, 100, 100);
1429  auto b = Rect::MakeXYWH(10, 10, 1, 1);
1430  auto expected = Rect::MakeXYWH(10, 10, 190, 190);
1431  test(a, b, expected);
1432  }
1433 
1434  {
1435  auto a = Rect::MakeXYWH(0, 0, 100, 100);
1436  auto b = Rect::MakeXYWH(10, 10, 100, 100);
1437  auto expected = Rect::MakeXYWH(0, 0, 110, 110);
1438  test(a, b, expected);
1439  }
1440 
1441  {
1442  auto a = Rect::MakeXYWH(0, 0, 100, 100);
1443  auto b = Rect::MakeXYWH(100, 100, 100, 100);
1444  auto expected = Rect::MakeXYWH(0, 0, 200, 200);
1445  test(a, b, expected);
1446  }
1447 }

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

◆ TEST() [333/465]

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

Definition at line 1172 of file rect_unittests.cc.

1172  {
1173  auto nan = std::numeric_limits<Scalar>::quiet_NaN();
1174 
1175  // Non-empty
1176  EXPECT_FALSE(Rect::MakeXYWH(1.5, 2.3, 10.5, 7.2).IsEmpty());
1177 
1178  // Empty both width and height both 0 or negative, in all combinations
1179  EXPECT_TRUE(Rect::MakeXYWH(1.5, 2.3, 0.0, 0.0).IsEmpty());
1180  EXPECT_TRUE(Rect::MakeXYWH(1.5, 2.3, -1.0, -1.0).IsEmpty());
1181  EXPECT_TRUE(Rect::MakeXYWH(1.5, 2.3, 0.0, -1.0).IsEmpty());
1182  EXPECT_TRUE(Rect::MakeXYWH(1.5, 2.3, -1.0, 0.0).IsEmpty());
1183 
1184  // Empty for 0 or negative width or height (but not both at the same time)
1185  EXPECT_TRUE(Rect::MakeXYWH(1.5, 2.3, 10.5, 0.0).IsEmpty());
1186  EXPECT_TRUE(Rect::MakeXYWH(1.5, 2.3, 10.5, -1.0).IsEmpty());
1187  EXPECT_TRUE(Rect::MakeXYWH(1.5, 2.3, 0.0, 7.2).IsEmpty());
1188  EXPECT_TRUE(Rect::MakeXYWH(1.5, 2.3, -1.0, 7.2).IsEmpty());
1189 
1190  // Empty for NaN in width or height or both
1191  EXPECT_TRUE(Rect::MakeXYWH(1.5, 2.3, 10.5, nan).IsEmpty());
1192  EXPECT_TRUE(Rect::MakeXYWH(1.5, 2.3, nan, 7.2).IsEmpty());
1193  EXPECT_TRUE(Rect::MakeXYWH(1.5, 2.3, nan, nan).IsEmpty());
1194 }

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

◆ TEST() [334/465]

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

Definition at line 3116 of file rect_unittests.cc.

3116  {
3117  {
3118  // This matrix should clip no corners.
3119  auto matrix = impeller::Matrix::MakeColumn(
3120  // clang-format off
3121  2.0f, 0.0f, 0.0f, 0.0f,
3122  0.0f, 4.0f, 0.0f, 0.0f,
3123  0.0f, 0.0f, 1.0f, 0.0f,
3124  0.0f, 0.0f, 0.0f, 8.0f
3125  // clang-format on
3126  );
3127  Rect src = Rect::MakeLTRB(100.0f, 100.0f, 200.0f, 200.0f);
3128  // None of these should have a W<0
3129  EXPECT_EQ(matrix.TransformHomogenous(src.GetLeftTop()),
3130  Vector3(200.0f, 400.0f, 8.0f));
3131  EXPECT_EQ(matrix.TransformHomogenous(src.GetRightTop()),
3132  Vector3(400.0f, 400.0f, 8.0f));
3133  EXPECT_EQ(matrix.TransformHomogenous(src.GetLeftBottom()),
3134  Vector3(200.0f, 800.0f, 8.0f));
3135  EXPECT_EQ(matrix.TransformHomogenous(src.GetRightBottom()),
3136  Vector3(400.0f, 800.0f, 8.0f));
3137 
3138  Rect expect = Rect::MakeLTRB(25.0f, 50.0f, 50.0f, 100.0f);
3139  EXPECT_FALSE(src.TransformAndClipBounds(matrix).IsEmpty());
3140  EXPECT_EQ(src.TransformAndClipBounds(matrix), expect);
3141  }
3142 
3143  {
3144  // This matrix should clip one corner.
3145  auto matrix = impeller::Matrix::MakeColumn(
3146  // clang-format off
3147  2.0f, 0.0f, 0.0f, -0.01f,
3148  0.0f, 2.0f, 0.0f, -0.006f,
3149  0.0f, 0.0f, 1.0f, 0.0f,
3150  0.0f, 0.0f, 0.0f, 3.0f
3151  // clang-format on
3152  );
3153  Rect src = Rect::MakeLTRB(100.0f, 100.0f, 200.0f, 200.0f);
3154  // Exactly one of these should have a W<0
3155  EXPECT_VECTOR3_NEAR(matrix.TransformHomogenous(src.GetLeftTop()),
3156  Vector3(200.0f, 200.0f, 1.4f));
3157  EXPECT_VECTOR3_NEAR(matrix.TransformHomogenous(src.GetRightTop()),
3158  Vector3(400.0f, 200.0f, 0.4f));
3159  EXPECT_VECTOR3_NEAR(matrix.TransformHomogenous(src.GetLeftBottom()),
3160  Vector3(200.0f, 400.0f, 0.8f));
3161  EXPECT_VECTOR3_NEAR(matrix.TransformHomogenous(src.GetRightBottom()),
3162  Vector3(400.0f, 400.0f, -0.2f));
3163 
3164  Rect expect = Rect::MakeLTRB(142.85715f, 142.85715f, 6553600.f, 6553600.f);
3165  EXPECT_FALSE(src.TransformAndClipBounds(matrix).IsEmpty());
3166  EXPECT_RECT_NEAR(src.TransformAndClipBounds(matrix), expect);
3167  }
3168 
3169  {
3170  // This matrix should clip two corners.
3171  auto matrix = impeller::Matrix::MakeColumn(
3172  // clang-format off
3173  2.0f, 0.0f, 0.0f, -.015f,
3174  0.0f, 2.0f, 0.0f, -.006f,
3175  0.0f, 0.0f, 1.0f, 0.0f,
3176  0.0f, 0.0f, 0.0f, 3.0f
3177  // clang-format on
3178  );
3179  Rect src = Rect::MakeLTRB(100.0f, 100.0f, 200.0f, 200.0f);
3180  // Exactly two of these should have a W<0
3181  EXPECT_VECTOR3_NEAR(matrix.TransformHomogenous(src.GetLeftTop()),
3182  Vector3(200.0f, 200.0f, 0.9f));
3183  EXPECT_VECTOR3_NEAR(matrix.TransformHomogenous(src.GetRightTop()),
3184  Vector3(400.0f, 200.0f, -0.6f));
3185  EXPECT_VECTOR3_NEAR(matrix.TransformHomogenous(src.GetLeftBottom()),
3186  Vector3(200.0f, 400.0f, 0.3f));
3187  EXPECT_VECTOR3_NEAR(matrix.TransformHomogenous(src.GetRightBottom()),
3188  Vector3(400.0f, 400.0f, -1.2f));
3189 
3190  Rect expect = Rect::MakeLTRB(222.2222f, 222.2222f, 5898373.f, 6553600.f);
3191  EXPECT_FALSE(src.TransformAndClipBounds(matrix).IsEmpty());
3192  EXPECT_RECT_NEAR(src.TransformAndClipBounds(matrix), expect);
3193  }
3194 
3195  {
3196  // This matrix should clip three corners.
3197  auto matrix = impeller::Matrix::MakeColumn(
3198  // clang-format off
3199  2.0f, 0.0f, 0.0f, -.02f,
3200  0.0f, 2.0f, 0.0f, -.006f,
3201  0.0f, 0.0f, 1.0f, 0.0f,
3202  0.0f, 0.0f, 0.0f, 3.0f
3203  // clang-format on
3204  );
3205  Rect src = Rect::MakeLTRB(100.0f, 100.0f, 200.0f, 200.0f);
3206  // Exactly three of these should have a W<0
3207  EXPECT_VECTOR3_NEAR(matrix.TransformHomogenous(src.GetLeftTop()),
3208  Vector3(200.0f, 200.0f, 0.4f));
3209  EXPECT_VECTOR3_NEAR(matrix.TransformHomogenous(src.GetRightTop()),
3210  Vector3(400.0f, 200.0f, -1.6f));
3211  EXPECT_VECTOR3_NEAR(matrix.TransformHomogenous(src.GetLeftBottom()),
3212  Vector3(200.0f, 400.0f, -0.2f));
3213  EXPECT_VECTOR3_NEAR(matrix.TransformHomogenous(src.GetRightBottom()),
3214  Vector3(400.0f, 400.0f, -2.2f));
3215 
3216  Rect expect = Rect::MakeLTRB(499.99988f, 499.99988f, 5898340.f, 4369400.f);
3217  EXPECT_FALSE(src.TransformAndClipBounds(matrix).IsEmpty());
3218  EXPECT_RECT_NEAR(src.TransformAndClipBounds(matrix), expect);
3219  }
3220 
3221  {
3222  // This matrix should clip all four corners.
3223  auto matrix = impeller::Matrix::MakeColumn(
3224  // clang-format off
3225  2.0f, 0.0f, 0.0f, -.025f,
3226  0.0f, 2.0f, 0.0f, -.006f,
3227  0.0f, 0.0f, 1.0f, 0.0f,
3228  0.0f, 0.0f, 0.0f, 3.0f
3229  // clang-format on
3230  );
3231  Rect src = Rect::MakeLTRB(100.0f, 100.0f, 200.0f, 200.0f);
3232  // All of these should have a W<0
3233  EXPECT_VECTOR3_NEAR(matrix.TransformHomogenous(src.GetLeftTop()),
3234  Vector3(200.0f, 200.0f, -0.1f));
3235  EXPECT_VECTOR3_NEAR(matrix.TransformHomogenous(src.GetRightTop()),
3236  Vector3(400.0f, 200.0f, -2.6f));
3237  EXPECT_VECTOR3_NEAR(matrix.TransformHomogenous(src.GetLeftBottom()),
3238  Vector3(200.0f, 400.0f, -0.7f));
3239  EXPECT_VECTOR3_NEAR(matrix.TransformHomogenous(src.GetRightBottom()),
3240  Vector3(400.0f, 400.0f, -3.2f));
3241 
3242  EXPECT_TRUE(src.TransformAndClipBounds(matrix).IsEmpty());
3243  }
3244 }
#define EXPECT_VECTOR3_NEAR(a, b)
static constexpr Matrix MakeColumn(Scalar m0, Scalar m1, Scalar m2, Scalar m3, Scalar m4, Scalar m5, Scalar m6, Scalar m7, Scalar m8, Scalar m9, Scalar m10, Scalar m11, Scalar m12, Scalar m13, Scalar m14, Scalar m15)
Definition: matrix.h:69

References EXPECT_RECT_NEAR, EXPECT_VECTOR3_NEAR, impeller::TRect< T >::GetLeftBottom(), impeller::TRect< T >::GetLeftTop(), impeller::TRect< T >::GetRightBottom(), impeller::TRect< T >::GetRightTop(), impeller::TRect< T >::IsEmpty(), impeller::Matrix::MakeColumn(), impeller::TRect< Scalar >::MakeLTRB(), and impeller::TRect< T >::TransformAndClipBounds().

◆ TEST() [335/465]

impeller::testing::TEST ( RenderPassBuilder  ,
CreatesMSAAResolveWithCorrectStore   
)

Definition at line 133 of file render_pass_builder_vk_unittests.cc.

133  {
134  RenderPassBuilderVK builder = RenderPassBuilderVK();
135  auto const context = MockVulkanContextBuilder().Build();
136 
137  // Create an MSAA color attachment.
138  builder.SetColorAttachment(0, PixelFormat::kR8G8B8A8UNormInt,
139  SampleCount::kCount4, LoadAction::kClear,
140  StoreAction::kMultisampleResolve);
141 
142  auto render_pass = builder.Build(context->GetDevice());
143 
144  EXPECT_TRUE(!!render_pass);
145 
146  auto maybe_color = builder.GetColor0();
147  ASSERT_TRUE(maybe_color.has_value());
148  if (!maybe_color.has_value()) {
149  return;
150  }
151  vk::AttachmentDescription color = maybe_color.value();
152 
153  // MSAA Texture.
154  EXPECT_EQ(color.initialLayout, vk::ImageLayout::eUndefined);
155  EXPECT_EQ(color.finalLayout, vk::ImageLayout::eGeneral);
156  EXPECT_EQ(color.loadOp, vk::AttachmentLoadOp::eClear);
157  EXPECT_EQ(color.storeOp, vk::AttachmentStoreOp::eDontCare);
158 
159  auto maybe_resolve = builder.GetColor0Resolve();
160  ASSERT_TRUE(maybe_resolve.has_value());
161  if (!maybe_resolve.has_value()) {
162  return;
163  }
164  vk::AttachmentDescription resolve = maybe_resolve.value();
165 
166  // MSAA Resolve Texture.
167  EXPECT_EQ(resolve.initialLayout, vk::ImageLayout::eUndefined);
168  EXPECT_EQ(resolve.finalLayout, vk::ImageLayout::eGeneral);
169  EXPECT_EQ(resolve.loadOp, vk::AttachmentLoadOp::eClear);
170  EXPECT_EQ(resolve.storeOp, vk::AttachmentStoreOp::eStore);
171 }

References impeller::RenderPassBuilderVK::Build(), impeller::RenderPassBuilderVK::GetColor0(), impeller::RenderPassBuilderVK::GetColor0Resolve(), impeller::kClear, impeller::kCount4, impeller::kMultisampleResolve, impeller::kR8G8B8A8UNormInt, and impeller::RenderPassBuilderVK::SetColorAttachment().

◆ TEST() [336/465]

impeller::testing::TEST ( RenderPassBuilder  ,
CreatesRenderPassWithCombinedDepthStencil   
)

Definition at line 56 of file render_pass_builder_vk_unittests.cc.

56  {
57  RenderPassBuilderVK builder = RenderPassBuilderVK();
58  auto const context = MockVulkanContextBuilder().Build();
59 
60  // Create a single color attachment with a transient depth stencil.
61  builder.SetColorAttachment(0, PixelFormat::kR8G8B8A8UNormInt,
62  SampleCount::kCount1, LoadAction::kClear,
63  StoreAction::kStore, vk::ImageLayout::eGeneral);
64  builder.SetDepthStencilAttachment(PixelFormat::kD24UnormS8Uint,
65  SampleCount::kCount1, LoadAction::kDontCare,
66  StoreAction::kDontCare);
67 
68  auto render_pass = builder.Build(context->GetDevice());
69 
70  EXPECT_TRUE(!!render_pass);
71 
72  std::optional<vk::AttachmentDescription> maybe_color = builder.GetColor0();
73  ASSERT_TRUE(maybe_color.has_value());
74  if (!maybe_color.has_value()) {
75  return;
76  }
77  vk::AttachmentDescription color = maybe_color.value();
78 
79  EXPECT_EQ(color.initialLayout, vk::ImageLayout::eUndefined);
80  EXPECT_EQ(color.finalLayout, vk::ImageLayout::eGeneral);
81  EXPECT_EQ(color.loadOp, vk::AttachmentLoadOp::eClear);
82  EXPECT_EQ(color.storeOp, vk::AttachmentStoreOp::eStore);
83 
84  std::optional<vk::AttachmentDescription> maybe_depth_stencil =
85  builder.GetDepthStencil();
86  ASSERT_TRUE(maybe_depth_stencil.has_value());
87  if (!maybe_depth_stencil.has_value()) {
88  return;
89  }
90  vk::AttachmentDescription depth_stencil = maybe_depth_stencil.value();
91 
92  EXPECT_EQ(depth_stencil.initialLayout, vk::ImageLayout::eUndefined);
93  EXPECT_EQ(depth_stencil.finalLayout,
94  vk::ImageLayout::eDepthStencilAttachmentOptimal);
95  EXPECT_EQ(depth_stencil.loadOp, vk::AttachmentLoadOp::eDontCare);
96  EXPECT_EQ(depth_stencil.storeOp, vk::AttachmentStoreOp::eDontCare);
97  EXPECT_EQ(depth_stencil.stencilLoadOp, vk::AttachmentLoadOp::eDontCare);
98  EXPECT_EQ(depth_stencil.stencilStoreOp, vk::AttachmentStoreOp::eDontCare);
99 }

References impeller::RenderPassBuilderVK::Build(), impeller::RenderPassBuilderVK::GetColor0(), impeller::RenderPassBuilderVK::GetDepthStencil(), impeller::kClear, impeller::kCount1, impeller::kD24UnormS8Uint, impeller::kDontCare, impeller::kR8G8B8A8UNormInt, impeller::kStore, impeller::RenderPassBuilderVK::SetColorAttachment(), and impeller::RenderPassBuilderVK::SetDepthStencilAttachment().

◆ TEST() [337/465]

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

impeller::testing::TEST ( RenderPassBuilder  ,
CreatesRenderPassWithOnlyStencil   
)

Definition at line 101 of file render_pass_builder_vk_unittests.cc.

101  {
102  RenderPassBuilderVK builder = RenderPassBuilderVK();
103  auto const context = MockVulkanContextBuilder().Build();
104 
105  // Create a single color attachment with a transient depth stencil.
106  builder.SetColorAttachment(0, PixelFormat::kR8G8B8A8UNormInt,
107  SampleCount::kCount1, LoadAction::kClear,
108  StoreAction::kStore);
109  builder.SetStencilAttachment(PixelFormat::kS8UInt, SampleCount::kCount1,
110  LoadAction::kDontCare, StoreAction::kDontCare);
111 
112  auto render_pass = builder.Build(context->GetDevice());
113 
114  EXPECT_TRUE(!!render_pass);
115 
116  std::optional<vk::AttachmentDescription> maybe_depth_stencil =
117  builder.GetDepthStencil();
118  ASSERT_TRUE(maybe_depth_stencil.has_value());
119  if (!maybe_depth_stencil.has_value()) {
120  return;
121  }
122  vk::AttachmentDescription depth_stencil = maybe_depth_stencil.value();
123 
124  EXPECT_EQ(depth_stencil.initialLayout, vk::ImageLayout::eUndefined);
125  EXPECT_EQ(depth_stencil.finalLayout,
126  vk::ImageLayout::eDepthStencilAttachmentOptimal);
127  EXPECT_EQ(depth_stencil.loadOp, vk::AttachmentLoadOp::eDontCare);
128  EXPECT_EQ(depth_stencil.storeOp, vk::AttachmentStoreOp::eDontCare);
129  EXPECT_EQ(depth_stencil.stencilLoadOp, vk::AttachmentLoadOp::eDontCare);
130  EXPECT_EQ(depth_stencil.stencilStoreOp, vk::AttachmentStoreOp::eDontCare);
131 }

References impeller::RenderPassBuilderVK::Build(), impeller::RenderPassBuilderVK::GetDepthStencil(), impeller::kClear, impeller::kCount1, impeller::kDontCare, impeller::kR8G8B8A8UNormInt, impeller::kS8UInt, impeller::kStore, impeller::RenderPassBuilderVK::SetColorAttachment(), and impeller::RenderPassBuilderVK::SetStencilAttachment().

◆ TEST() [339/465]

impeller::testing::TEST ( RenderPassBuilder  ,
RenderPassWithLoadOpUsesCurrentLayout   
)

Definition at line 30 of file render_pass_builder_vk_unittests.cc.

30  {
31  RenderPassBuilderVK builder = RenderPassBuilderVK();
32  auto const context = MockVulkanContextBuilder().Build();
33 
34  builder.SetColorAttachment(0, PixelFormat::kR8G8B8A8UNormInt,
35  SampleCount::kCount1, LoadAction::kLoad,
36  StoreAction::kStore,
37  vk::ImageLayout::eColorAttachmentOptimal);
38 
39  auto render_pass = builder.Build(context->GetDevice());
40 
41  EXPECT_TRUE(!!render_pass);
42 
43  std::optional<vk::AttachmentDescription> maybe_color = builder.GetColor0();
44  ASSERT_TRUE(maybe_color.has_value());
45  if (!maybe_color.has_value()) {
46  return;
47  }
48  vk::AttachmentDescription color = maybe_color.value();
49 
50  EXPECT_EQ(color.initialLayout, vk::ImageLayout::eColorAttachmentOptimal);
51  EXPECT_EQ(color.finalLayout, vk::ImageLayout::eGeneral);
52  EXPECT_EQ(color.loadOp, vk::AttachmentLoadOp::eLoad);
53  EXPECT_EQ(color.storeOp, vk::AttachmentStoreOp::eStore);
54 }

References impeller::RenderPassBuilderVK::Build(), impeller::RenderPassBuilderVK::GetColor0(), impeller::kCount1, impeller::kLoad, impeller::kR8G8B8A8UNormInt, impeller::kStore, and impeller::RenderPassBuilderVK::SetColorAttachment().

◆ TEST() [340/465]

impeller::testing::TEST ( ResourceManagerVKTest  ,
CreatesANewInstance   
)

Definition at line 18 of file resource_manager_vk_unittests.cc.

18  {
19  auto const a = ResourceManagerVK::Create();
20  auto const b = ResourceManagerVK::Create();
21  EXPECT_NE(a, b);
22 }
ScopedObject< Object > Create(CtorArgs &&... args)
Definition: object.h:160

References impeller::saturated::b, and impeller::ResourceManagerVK::Create().

◆ TEST() [341/465]

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

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

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

impeller::testing::TEST ( RoundRectTest  ,
ContractAndRequireRadiiAdjustment   
)

Definition at line 802 of file round_rect_unittests.cc.

802  {
803  RoundRect round_rect =
804  RoundRect::MakeRectRadii(Rect::MakeXYWH(10.0f, 10.0f, 30.0f, 30.0f),
805  {
806  .top_left = Size(1.0f, 2.0f),
807  .top_right = Size(3.0f, 4.0f),
808  .bottom_left = Size(5.0f, 6.0f),
809  .bottom_right = Size(7.0f, 8.0f),
810  });
811  RoundRect expanded = round_rect.Expand(-12.0);
812  // Largest sum of paired radii sizes are the bottom and right edges
813  // both of which sum to 12
814  // Rect was 30x30 reduced by 12 on all sides leaving only 6x6, so all
815  // radii are scaled by half to avoid overflowing the contracted rect
816 
817  EXPECT_FALSE(expanded.IsEmpty());
818  EXPECT_FALSE(expanded.IsRect());
819  EXPECT_FALSE(expanded.IsOval());
820  EXPECT_TRUE(expanded.IsFinite());
821  EXPECT_FALSE(expanded.GetBounds().IsEmpty());
822  EXPECT_EQ(expanded.GetBounds(), Rect::MakeLTRB(22.0f, 22.0f, 28.0f, 28.0f));
823  EXPECT_EQ(expanded.GetRadii().top_left, Size(0.5f, 1.0f));
824  EXPECT_EQ(expanded.GetRadii().top_right, Size(1.5f, 2.0f));
825  EXPECT_EQ(expanded.GetRadii().bottom_left, Size(2.5f, 3.0f));
826  EXPECT_EQ(expanded.GetRadii().bottom_right, Size(3.5f, 4.0f));
827 
828  // In this test, the MakeRectRadii constructor will make the same
829  // adjustment to the radii that the Expand method applied.
830  EXPECT_EQ(expanded,
831  RoundRect::MakeRectRadii(Rect::MakeXYWH(22.0f, 22.0f, 6.0f, 6.0f),
832  {
833  .top_left = Size(1.0f, 2.0f),
834  .top_right = Size(3.0f, 4.0f),
835  .bottom_left = Size(5.0f, 6.0f),
836  .bottom_right = Size(7.0f, 8.0f),
837  }));
838 
839  // In this test, the arguments to the constructor supply the correctly
840  // adjusted radii (though there is no real way to tell other than
841  // the result is the same).
842  EXPECT_EQ(expanded,
843  RoundRect::MakeRectRadii(Rect::MakeXYWH(22.0f, 22.0f, 6.0f, 6.0f),
844  {
845  .top_left = Size(0.5f, 1.0f),
846  .top_right = Size(1.5f, 2.0f),
847  .bottom_left = Size(2.5f, 3.0f),
848  .bottom_right = Size(3.5f, 4.0f),
849  }));
850 }

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

◆ TEST() [345/465]

impeller::testing::TEST ( RoundRectTest  ,
ContractFourScalars   
)

Definition at line 770 of file round_rect_unittests.cc.

770  {
771  RoundRect round_rect =
772  RoundRect::MakeRectRadii(Rect::MakeXYWH(10.0f, 10.0f, 30.0f, 30.0f),
773  {
774  .top_left = Size(1.0f, 2.0f),
775  .top_right = Size(3.0f, 4.0f),
776  .bottom_left = Size(5.0f, 6.0f),
777  .bottom_right = Size(7.0f, 8.0f),
778  });
779  RoundRect expanded = round_rect.Expand(-1.0, -1.5, -2.0, -2.5);
780 
781  EXPECT_FALSE(expanded.IsEmpty());
782  EXPECT_FALSE(expanded.IsRect());
783  EXPECT_FALSE(expanded.IsOval());
784  EXPECT_TRUE(expanded.IsFinite());
785  EXPECT_FALSE(expanded.GetBounds().IsEmpty());
786  EXPECT_EQ(expanded.GetBounds(), Rect::MakeLTRB(11.0f, 11.5f, 38.0f, 37.5f));
787  EXPECT_EQ(expanded.GetRadii().top_left, Size(1.0f, 2.0f));
788  EXPECT_EQ(expanded.GetRadii().top_right, Size(3.0f, 4.0f));
789  EXPECT_EQ(expanded.GetRadii().bottom_left, Size(5.0f, 6.0f));
790  EXPECT_EQ(expanded.GetRadii().bottom_right, Size(7.0f, 8.0f));
791 
792  EXPECT_EQ(expanded,
793  RoundRect::MakeRectRadii(Rect::MakeXYWH(11.0f, 11.5f, 27.0f, 26.0f),
794  {
795  .top_left = Size(1.0f, 2.0f),
796  .top_right = Size(3.0f, 4.0f),
797  .bottom_left = Size(5.0f, 6.0f),
798  .bottom_right = Size(7.0f, 8.0f),
799  }));
800 }

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

◆ TEST() [346/465]

impeller::testing::TEST ( RoundRectTest  ,
ContractScalar   
)

Definition at line 706 of file round_rect_unittests.cc.

706  {
707  RoundRect round_rect =
708  RoundRect::MakeRectRadii(Rect::MakeXYWH(10.0f, 10.0f, 30.0f, 30.0f),
709  {
710  .top_left = Size(1.0f, 2.0f),
711  .top_right = Size(3.0f, 4.0f),
712  .bottom_left = Size(5.0f, 6.0f),
713  .bottom_right = Size(7.0f, 8.0f),
714  });
715  RoundRect expanded = round_rect.Expand(-2.0);
716 
717  EXPECT_FALSE(expanded.IsEmpty());
718  EXPECT_FALSE(expanded.IsRect());
719  EXPECT_FALSE(expanded.IsOval());
720  EXPECT_TRUE(expanded.IsFinite());
721  EXPECT_FALSE(expanded.GetBounds().IsEmpty());
722  EXPECT_EQ(expanded.GetBounds(), Rect::MakeLTRB(12.0f, 12.0f, 38.0f, 38.0f));
723  EXPECT_EQ(expanded.GetRadii().top_left, Size(1.0f, 2.0f));
724  EXPECT_EQ(expanded.GetRadii().top_right, Size(3.0f, 4.0f));
725  EXPECT_EQ(expanded.GetRadii().bottom_left, Size(5.0f, 6.0f));
726  EXPECT_EQ(expanded.GetRadii().bottom_right, Size(7.0f, 8.0f));
727 
728  EXPECT_EQ(expanded,
729  RoundRect::MakeRectRadii(Rect::MakeXYWH(12.0f, 12.0f, 26.0f, 26.0f),
730  {
731  .top_left = Size(1.0f, 2.0f),
732  .top_right = Size(3.0f, 4.0f),
733  .bottom_left = Size(5.0f, 6.0f),
734  .bottom_right = Size(7.0f, 8.0f),
735  }));
736 }

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

◆ TEST() [347/465]

impeller::testing::TEST ( RoundRectTest  ,
ContractTwoScalars   
)

Definition at line 738 of file round_rect_unittests.cc.

738  {
739  RoundRect round_rect =
740  RoundRect::MakeRectRadii(Rect::MakeXYWH(10.0f, 10.0f, 30.0f, 30.0f),
741  {
742  .top_left = Size(1.0f, 2.0f),
743  .top_right = Size(3.0f, 4.0f),
744  .bottom_left = Size(5.0f, 6.0f),
745  .bottom_right = Size(7.0f, 8.0f),
746  });
747  RoundRect expanded = round_rect.Expand(-1.0, -2.0);
748 
749  EXPECT_FALSE(expanded.IsEmpty());
750  EXPECT_FALSE(expanded.IsRect());
751  EXPECT_FALSE(expanded.IsOval());
752  EXPECT_TRUE(expanded.IsFinite());
753  EXPECT_FALSE(expanded.GetBounds().IsEmpty());
754  EXPECT_EQ(expanded.GetBounds(), Rect::MakeLTRB(11.0f, 12.0f, 39.0f, 38.0f));
755  EXPECT_EQ(expanded.GetRadii().top_left, Size(1.0f, 2.0f));
756  EXPECT_EQ(expanded.GetRadii().top_right, Size(3.0f, 4.0f));
757  EXPECT_EQ(expanded.GetRadii().bottom_left, Size(5.0f, 6.0f));
758  EXPECT_EQ(expanded.GetRadii().bottom_right, Size(7.0f, 8.0f));
759 
760  EXPECT_EQ(expanded,
761  RoundRect::MakeRectRadii(Rect::MakeXYWH(11.0f, 12.0f, 28.0f, 26.0f),
762  {
763  .top_left = Size(1.0f, 2.0f),
764  .top_right = Size(3.0f, 4.0f),
765  .bottom_left = Size(5.0f, 6.0f),
766  .bottom_right = Size(7.0f, 8.0f),
767  }));
768 }

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

◆ TEST() [348/465]

impeller::testing::TEST ( RoundRectTest  ,
DefaultConstructor   
)

Definition at line 347 of file round_rect_unittests.cc.

347  {
348  RoundRect round_rect = RoundRect();
349 
350  EXPECT_TRUE(round_rect.IsEmpty());
351  EXPECT_FALSE(round_rect.IsRect());
352  EXPECT_FALSE(round_rect.IsOval());
353  EXPECT_TRUE(round_rect.IsFinite());
354  EXPECT_TRUE(round_rect.GetBounds().IsEmpty());
355  EXPECT_EQ(round_rect.GetBounds(), Rect());
356  EXPECT_EQ(round_rect.GetRadii().top_left, Size());
357  EXPECT_EQ(round_rect.GetRadii().top_right, Size());
358  EXPECT_EQ(round_rect.GetRadii().bottom_left, Size());
359  EXPECT_EQ(round_rect.GetRadii().bottom_right, Size());
360 }

References impeller::RoundingRadii::bottom_left, impeller::RoundingRadii::bottom_right, impeller::RoundRect::GetBounds(), impeller::RoundRect::GetRadii(), impeller::TRect< T >::IsEmpty(), impeller::RoundRect::IsEmpty(), impeller::RoundRect::IsFinite(), impeller::RoundRect::IsOval(), impeller::RoundRect::IsRect(), impeller::RoundingRadii::top_left, and impeller::RoundingRadii::top_right.

◆ TEST() [349/465]

impeller::testing::TEST ( RoundRectTest  ,
DifferingCornersRoundRectContains   
)

Definition at line 958 of file round_rect_unittests.cc.

958  {
959  Rect bounds = Rect::MakeLTRB(-50.0f, -50.0f, 50.0f, 50.0f);
960  auto round_rect =
961  RoundRect::MakeRectRadii(bounds, {
962  .top_left = Size(2.0, 3.0),
963  .top_right = Size(4.0, 5.0),
964  .bottom_left = Size(6.0, 7.0),
965  .bottom_right = Size(8.0, 9.0),
966  });
967 
968  // For a corner with radii {A, B}, the "45 degree point" on the
969  // corner curve will be at an offset of:
970  //
971  // (A * sqrt(2) / 2, B * sqrt(2) / 2)
972  //
973  // And the center(s) of these corners are at:
974  //
975  // (+/-(50 - A), +/-(50 - B))
976  auto coord = [](Scalar radius) {
977  return 50 - radius + radius * kSqrt2 / 2.0f - kEhCloseEnough;
978  };
979  auto coord_in = [&coord](Scalar radius) {
980  return coord(radius) - kEhCloseEnough;
981  };
982  auto coord_out = [&coord](Scalar radius) {
983  // For some reason 1 kEhCloseEnough is not enough to put us outside
984  // in some of the cases, so we use 2x the epsilon.
985  return coord(radius) + 2 * kEhCloseEnough;
986  };
987  // Upper left corner (radii = {2.0, 3.0})
988  EXPECT_TRUE(round_rect.Contains({-coord_in(2.0), -coord_in(3.0)}));
989  EXPECT_FALSE(round_rect.Contains({-coord_out(2.0), -coord_out(3.0)}));
990  // Upper right corner (radii = {4.0, 5.0})
991  EXPECT_TRUE(round_rect.Contains({coord_in(4.0), -coord_in(5.0)}));
992  EXPECT_FALSE(round_rect.Contains({coord_out(4.0), -coord_out(5.0)}));
993  // Lower left corner (radii = {6.0, 7.0})
994  EXPECT_TRUE(round_rect.Contains({-coord_in(6.0), coord_in(7.0)}));
995  EXPECT_FALSE(round_rect.Contains({-coord_out(6.0), coord_out(7.0)}));
996  // Lower right corner (radii = {8.0, 9.0})
997  EXPECT_TRUE(round_rect.Contains({coord_in(8.0), coord_in(9.0)}));
998  EXPECT_FALSE(round_rect.Contains({coord_out(8.0), coord_out(9.0)}));
999 }
constexpr float kSqrt2
Definition: constants.h:47

References impeller::kEhCloseEnough, impeller::kSqrt2, impeller::TRect< Scalar >::MakeLTRB(), and impeller::RoundRect::MakeRectRadii().

◆ TEST() [350/465]

impeller::testing::TEST ( RoundRectTest  ,
EmptyDeclaration   
)

Definition at line 320 of file round_rect_unittests.cc.

320  {
321  RoundRect round_rect;
322 
323  EXPECT_TRUE(round_rect.IsEmpty());
324  EXPECT_FALSE(round_rect.IsRect());
325  EXPECT_FALSE(round_rect.IsOval());
326  EXPECT_TRUE(round_rect.IsFinite());
327  EXPECT_TRUE(round_rect.GetBounds().IsEmpty());
328  EXPECT_EQ(round_rect.GetBounds(), Rect());
329  EXPECT_EQ(round_rect.GetBounds().GetLeft(), 0.0f);
330  EXPECT_EQ(round_rect.GetBounds().GetTop(), 0.0f);
331  EXPECT_EQ(round_rect.GetBounds().GetRight(), 0.0f);
332  EXPECT_EQ(round_rect.GetBounds().GetBottom(), 0.0f);
333  EXPECT_EQ(round_rect.GetRadii().top_left, Size());
334  EXPECT_EQ(round_rect.GetRadii().top_right, Size());
335  EXPECT_EQ(round_rect.GetRadii().bottom_left, Size());
336  EXPECT_EQ(round_rect.GetRadii().bottom_right, Size());
337  EXPECT_EQ(round_rect.GetRadii().top_left.width, 0.0f);
338  EXPECT_EQ(round_rect.GetRadii().top_left.height, 0.0f);
339  EXPECT_EQ(round_rect.GetRadii().top_right.width, 0.0f);
340  EXPECT_EQ(round_rect.GetRadii().top_right.height, 0.0f);
341  EXPECT_EQ(round_rect.GetRadii().bottom_left.width, 0.0f);
342  EXPECT_EQ(round_rect.GetRadii().bottom_left.height, 0.0f);
343  EXPECT_EQ(round_rect.GetRadii().bottom_right.width, 0.0f);
344  EXPECT_EQ(round_rect.GetRadii().bottom_right.height, 0.0f);
345 }

References impeller::RoundingRadii::bottom_left, impeller::RoundingRadii::bottom_right, impeller::TRect< T >::GetBottom(), impeller::RoundRect::GetBounds(), impeller::TRect< T >::GetLeft(), impeller::RoundRect::GetRadii(), impeller::TRect< T >::GetRight(), impeller::TRect< T >::GetTop(), impeller::TSize< T >::height, impeller::TRect< T >::IsEmpty(), impeller::RoundRect::IsEmpty(), impeller::RoundRect::IsFinite(), impeller::RoundRect::IsOval(), impeller::RoundRect::IsRect(), impeller::RoundingRadii::top_left, impeller::RoundingRadii::top_right, and impeller::TSize< T >::width.

◆ TEST() [351/465]

impeller::testing::TEST ( RoundRectTest  ,
EmptyOvalConstruction   
)

Definition at line 410 of file round_rect_unittests.cc.

410  {
411  RoundRect round_rect = RoundRect::MakeRectXY(
412  Rect::MakeLTRB(20.0f, 20.0f, 20.0f, 20.0f), 10.0f, 10.0f);
413 
414  EXPECT_TRUE(round_rect.IsEmpty());
415  EXPECT_FALSE(round_rect.IsRect());
416  EXPECT_FALSE(round_rect.IsOval());
417  EXPECT_TRUE(round_rect.IsFinite());
418  EXPECT_TRUE(round_rect.GetBounds().IsEmpty());
419  EXPECT_EQ(round_rect.GetBounds(), Rect::MakeLTRB(20.0f, 20.0f, 20.0f, 20.0f));
420  EXPECT_EQ(round_rect.GetRadii().top_left, Size());
421  EXPECT_EQ(round_rect.GetRadii().top_right, Size());
422  EXPECT_EQ(round_rect.GetRadii().bottom_left, Size());
423  EXPECT_EQ(round_rect.GetRadii().bottom_right, Size());
424 }

References impeller::RoundingRadii::bottom_left, impeller::RoundingRadii::bottom_right, impeller::RoundRect::GetBounds(), impeller::RoundRect::GetRadii(), impeller::TRect< T >::IsEmpty(), impeller::RoundRect::IsEmpty(), impeller::RoundRect::IsFinite(), impeller::RoundRect::IsOval(), impeller::RoundRect::IsRect(), impeller::TRect< Scalar >::MakeLTRB(), impeller::RoundRect::MakeRectXY(), impeller::RoundingRadii::top_left, and impeller::RoundingRadii::top_right.

◆ TEST() [352/465]

impeller::testing::TEST ( RoundRectTest  ,
EmptyRectConstruction   
)

Definition at line 362 of file round_rect_unittests.cc.

362  {
363  RoundRect round_rect =
364  RoundRect::MakeRect(Rect::MakeLTRB(20.0f, 20.0f, 20.0f, 20.0f));
365 
366  EXPECT_TRUE(round_rect.IsEmpty());
367  EXPECT_FALSE(round_rect.IsRect());
368  EXPECT_FALSE(round_rect.IsOval());
369  EXPECT_TRUE(round_rect.IsFinite());
370  EXPECT_TRUE(round_rect.GetBounds().IsEmpty());
371  EXPECT_EQ(round_rect.GetBounds(), Rect::MakeLTRB(20.0f, 20.0f, 20.0f, 20.0f));
372  EXPECT_EQ(round_rect.GetRadii().top_left, Size());
373  EXPECT_EQ(round_rect.GetRadii().top_right, Size());
374  EXPECT_EQ(round_rect.GetRadii().bottom_left, Size());
375  EXPECT_EQ(round_rect.GetRadii().bottom_right, Size());
376 }

References impeller::RoundingRadii::bottom_left, impeller::RoundingRadii::bottom_right, impeller::RoundRect::GetBounds(), impeller::RoundRect::GetRadii(), impeller::TRect< T >::IsEmpty(), impeller::RoundRect::IsEmpty(), impeller::RoundRect::IsFinite(), impeller::RoundRect::IsOval(), impeller::RoundRect::IsRect(), impeller::TRect< Scalar >::MakeLTRB(), impeller::RoundRect::MakeRect(), impeller::RoundingRadii::top_left, and impeller::RoundingRadii::top_right.

◆ TEST() [353/465]

impeller::testing::TEST ( RoundRectTest  ,
ExpandFourScalars   
)

Definition at line 674 of file round_rect_unittests.cc.

674  {
675  RoundRect round_rect =
676  RoundRect::MakeRectRadii(Rect::MakeXYWH(10.0f, 10.0f, 30.0f, 30.0f),
677  {
678  .top_left = Size(1.0f, 2.0f),
679  .top_right = Size(3.0f, 4.0f),
680  .bottom_left = Size(5.0f, 6.0f),
681  .bottom_right = Size(7.0f, 8.0f),
682  });
683  RoundRect expanded = round_rect.Expand(5.0, 6.0, 7.0, 8.0);
684 
685  EXPECT_FALSE(expanded.IsEmpty());
686  EXPECT_FALSE(expanded.IsRect());
687  EXPECT_FALSE(expanded.IsOval());
688  EXPECT_TRUE(expanded.IsFinite());
689  EXPECT_FALSE(expanded.GetBounds().IsEmpty());
690  EXPECT_EQ(expanded.GetBounds(), Rect::MakeLTRB(5.0f, 4.0f, 47.0f, 48.0f));
691  EXPECT_EQ(expanded.GetRadii().top_left, Size(1.0f, 2.0f));
692  EXPECT_EQ(expanded.GetRadii().top_right, Size(3.0f, 4.0f));
693  EXPECT_EQ(expanded.GetRadii().bottom_left, Size(5.0f, 6.0f));
694  EXPECT_EQ(expanded.GetRadii().bottom_right, Size(7.0f, 8.0f));
695 
696  EXPECT_EQ(expanded,
697  RoundRect::MakeRectRadii(Rect::MakeXYWH(5.0f, 4.0f, 42.0f, 44.0f),
698  {
699  .top_left = Size(1.0f, 2.0f),
700  .top_right = Size(3.0f, 4.0f),
701  .bottom_left = Size(5.0f, 6.0f),
702  .bottom_right = Size(7.0f, 8.0f),
703  }));
704 }

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

◆ TEST() [354/465]

impeller::testing::TEST ( RoundRectTest  ,
ExpandScalar   
)

Definition at line 610 of file round_rect_unittests.cc.

610  {
611  RoundRect round_rect =
612  RoundRect::MakeRectRadii(Rect::MakeXYWH(10.0f, 10.0f, 30.0f, 30.0f),
613  {
614  .top_left = Size(1.0f, 2.0f),
615  .top_right = Size(3.0f, 4.0f),
616  .bottom_left = Size(5.0f, 6.0f),
617  .bottom_right = Size(7.0f, 8.0f),
618  });
619  RoundRect expanded = round_rect.Expand(5.0);
620 
621  EXPECT_FALSE(expanded.IsEmpty());
622  EXPECT_FALSE(expanded.IsRect());
623  EXPECT_FALSE(expanded.IsOval());
624  EXPECT_TRUE(expanded.IsFinite());
625  EXPECT_FALSE(expanded.GetBounds().IsEmpty());
626  EXPECT_EQ(expanded.GetBounds(), Rect::MakeLTRB(5.0f, 5.0f, 45.0f, 45.0f));
627  EXPECT_EQ(expanded.GetRadii().top_left, Size(1.0f, 2.0f));
628  EXPECT_EQ(expanded.GetRadii().top_right, Size(3.0f, 4.0f));
629  EXPECT_EQ(expanded.GetRadii().bottom_left, Size(5.0f, 6.0f));
630  EXPECT_EQ(expanded.GetRadii().bottom_right, Size(7.0f, 8.0f));
631 
632  EXPECT_EQ(expanded,
633  RoundRect::MakeRectRadii(Rect::MakeXYWH(5.0f, 5.0f, 40.0f, 40.0f),
634  {
635  .top_left = Size(1.0f, 2.0f),
636  .top_right = Size(3.0f, 4.0f),
637  .bottom_left = Size(5.0f, 6.0f),
638  .bottom_right = Size(7.0f, 8.0f),
639  }));
640 }

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

◆ TEST() [355/465]

impeller::testing::TEST ( RoundRectTest  ,
ExpandTwoScalars   
)

Definition at line 642 of file round_rect_unittests.cc.

642  {
643  RoundRect round_rect =
644  RoundRect::MakeRectRadii(Rect::MakeXYWH(10.0f, 10.0f, 30.0f, 30.0f),
645  {
646  .top_left = Size(1.0f, 2.0f),
647  .top_right = Size(3.0f, 4.0f),
648  .bottom_left = Size(5.0f, 6.0f),
649  .bottom_right = Size(7.0f, 8.0f),
650  });
651  RoundRect expanded = round_rect.Expand(5.0, 6.0);
652 
653  EXPECT_FALSE(expanded.IsEmpty());
654  EXPECT_FALSE(expanded.IsRect());
655  EXPECT_FALSE(expanded.IsOval());
656  EXPECT_TRUE(expanded.IsFinite());
657  EXPECT_FALSE(expanded.GetBounds().IsEmpty());
658  EXPECT_EQ(expanded.GetBounds(), Rect::MakeLTRB(5.0f, 4.0f, 45.0f, 46.0f));
659  EXPECT_EQ(expanded.GetRadii().top_left, Size(1.0f, 2.0f));
660  EXPECT_EQ(expanded.GetRadii().top_right, Size(3.0f, 4.0f));
661  EXPECT_EQ(expanded.GetRadii().bottom_left, Size(5.0f, 6.0f));
662  EXPECT_EQ(expanded.GetRadii().bottom_right, Size(7.0f, 8.0f));
663 
664  EXPECT_EQ(expanded,
665  RoundRect::MakeRectRadii(Rect::MakeXYWH(5.0f, 4.0f, 40.0f, 42.0f),
666  {
667  .top_left = Size(1.0f, 2.0f),
668  .top_right = Size(3.0f, 4.0f),
669  .bottom_left = Size(5.0f, 6.0f),
670  .bottom_right = Size(7.0f, 8.0f),
671  }));
672 }

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

◆ TEST() [356/465]

impeller::testing::TEST ( RoundRectTest  ,
InvertedOvalConstruction   
)

Definition at line 442 of file round_rect_unittests.cc.

442  {
443  RoundRect round_rect = RoundRect::MakeRectXY(
444  Rect::MakeLTRB(20.0f, 20.0f, 10.0f, 10.0f), 10.0f, 10.0f);
445 
446  EXPECT_FALSE(round_rect.IsEmpty());
447  EXPECT_FALSE(round_rect.IsRect());
448  EXPECT_TRUE(round_rect.IsOval());
449  EXPECT_TRUE(round_rect.IsFinite());
450  EXPECT_FALSE(round_rect.GetBounds().IsEmpty());
451  EXPECT_EQ(round_rect.GetBounds(), Rect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f));
452  EXPECT_EQ(round_rect.GetRadii().top_left, Size(5.0f, 5.0f));
453  EXPECT_EQ(round_rect.GetRadii().top_right, Size(5.0f, 5.0f));
454  EXPECT_EQ(round_rect.GetRadii().bottom_left, Size(5.0f, 5.0f));
455  EXPECT_EQ(round_rect.GetRadii().bottom_right, Size(5.0f, 5.0f));
456 }

References impeller::RoundingRadii::bottom_left, impeller::RoundingRadii::bottom_right, impeller::RoundRect::GetBounds(), impeller::RoundRect::GetRadii(), impeller::TRect< T >::IsEmpty(), impeller::RoundRect::IsEmpty(), impeller::RoundRect::IsFinite(), impeller::RoundRect::IsOval(), impeller::RoundRect::IsRect(), impeller::TRect< Scalar >::MakeLTRB(), impeller::RoundRect::MakeRectXY(), impeller::RoundingRadii::top_left, and impeller::RoundingRadii::top_right.

◆ TEST() [357/465]

impeller::testing::TEST ( RoundRectTest  ,
InvertedRectConstruction   
)

Definition at line 394 of file round_rect_unittests.cc.

394  {
395  RoundRect round_rect =
396  RoundRect::MakeRect(Rect::MakeLTRB(20.0f, 20.0f, 10.0f, 10.0f));
397 
398  EXPECT_FALSE(round_rect.IsEmpty());
399  EXPECT_TRUE(round_rect.IsRect());
400  EXPECT_FALSE(round_rect.IsOval());
401  EXPECT_TRUE(round_rect.IsFinite());
402  EXPECT_FALSE(round_rect.GetBounds().IsEmpty());
403  EXPECT_EQ(round_rect.GetBounds(), Rect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f));
404  EXPECT_EQ(round_rect.GetRadii().top_left, Size());
405  EXPECT_EQ(round_rect.GetRadii().top_right, Size());
406  EXPECT_EQ(round_rect.GetRadii().bottom_left, Size());
407  EXPECT_EQ(round_rect.GetRadii().bottom_right, Size());
408 }

References impeller::RoundingRadii::bottom_left, impeller::RoundingRadii::bottom_right, impeller::RoundRect::GetBounds(), impeller::RoundRect::GetRadii(), impeller::TRect< T >::IsEmpty(), impeller::RoundRect::IsEmpty(), impeller::RoundRect::IsFinite(), impeller::RoundRect::IsOval(), impeller::RoundRect::IsRect(), impeller::TRect< Scalar >::MakeLTRB(), impeller::RoundRect::MakeRect(), impeller::RoundingRadii::top_left, and impeller::RoundingRadii::top_right.

◆ TEST() [358/465]

impeller::testing::TEST ( RoundRectTest  ,
NoCornerRoundRectContains   
)

Definition at line 852 of file round_rect_unittests.cc.

852  {
853  Rect bounds = Rect::MakeLTRB(-50.0f, -50.0f, 50.0f, 50.0f);
854  // RRect of bounds with no corners contains corners just barely
855  auto no_corners = RoundRect::MakeRectXY(bounds, 0.0f, 0.0f);
856 
857  EXPECT_TRUE(no_corners.Contains({-50, -50}));
858  // Rectangles have half-in, half-out containment so we need
859  // to be careful about testing containment of right/bottom corners.
860  EXPECT_TRUE(no_corners.Contains({-50, 49.99}));
861  EXPECT_TRUE(no_corners.Contains({49.99, -50}));
862  EXPECT_TRUE(no_corners.Contains({49.99, 49.99}));
863  EXPECT_FALSE(no_corners.Contains({-50.01, -50}));
864  EXPECT_FALSE(no_corners.Contains({-50, -50.01}));
865  EXPECT_FALSE(no_corners.Contains({-50.01, 50}));
866  EXPECT_FALSE(no_corners.Contains({-50, 50.01}));
867  EXPECT_FALSE(no_corners.Contains({50.01, -50}));
868  EXPECT_FALSE(no_corners.Contains({50, -50.01}));
869  EXPECT_FALSE(no_corners.Contains({50.01, 50}));
870  EXPECT_FALSE(no_corners.Contains({50, 50.01}));
871 }

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

◆ TEST() [359/465]

impeller::testing::TEST ( RoundRectTest  ,
OvalConstructor   
)

Definition at line 426 of file round_rect_unittests.cc.

426  {
427  RoundRect round_rect =
428  RoundRect::MakeOval(Rect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f));
429 
430  EXPECT_FALSE(round_rect.IsEmpty());
431  EXPECT_FALSE(round_rect.IsRect());
432  EXPECT_TRUE(round_rect.IsOval());
433  EXPECT_TRUE(round_rect.IsFinite());
434  EXPECT_FALSE(round_rect.GetBounds().IsEmpty());
435  EXPECT_EQ(round_rect.GetBounds(), Rect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f));
436  EXPECT_EQ(round_rect.GetRadii().top_left, Size(5.0f, 5.0f));
437  EXPECT_EQ(round_rect.GetRadii().top_right, Size(5.0f, 5.0f));
438  EXPECT_EQ(round_rect.GetRadii().bottom_left, Size(5.0f, 5.0f));
439  EXPECT_EQ(round_rect.GetRadii().bottom_right, Size(5.0f, 5.0f));
440 }

References impeller::RoundingRadii::bottom_left, impeller::RoundingRadii::bottom_right, impeller::RoundRect::GetBounds(), impeller::RoundRect::GetRadii(), impeller::TRect< T >::IsEmpty(), impeller::RoundRect::IsEmpty(), impeller::RoundRect::IsFinite(), impeller::RoundRect::IsOval(), impeller::RoundRect::IsRect(), impeller::TRect< Scalar >::MakeLTRB(), impeller::RoundRect::MakeOval(), impeller::RoundingRadii::top_left, and impeller::RoundingRadii::top_right.

◆ TEST() [360/465]

impeller::testing::TEST ( RoundRectTest  ,
RectConstructor   
)

Definition at line 378 of file round_rect_unittests.cc.

378  {
379  RoundRect round_rect =
380  RoundRect::MakeRect(Rect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f));
381 
382  EXPECT_FALSE(round_rect.IsEmpty());
383  EXPECT_TRUE(round_rect.IsRect());
384  EXPECT_FALSE(round_rect.IsOval());
385  EXPECT_TRUE(round_rect.IsFinite());
386  EXPECT_FALSE(round_rect.GetBounds().IsEmpty());
387  EXPECT_EQ(round_rect.GetBounds(), Rect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f));
388  EXPECT_EQ(round_rect.GetRadii().top_left, Size());
389  EXPECT_EQ(round_rect.GetRadii().top_right, Size());
390  EXPECT_EQ(round_rect.GetRadii().bottom_left, Size());
391  EXPECT_EQ(round_rect.GetRadii().bottom_right, Size());
392 }

References impeller::RoundingRadii::bottom_left, impeller::RoundingRadii::bottom_right, impeller::RoundRect::GetBounds(), impeller::RoundRect::GetRadii(), impeller::TRect< T >::IsEmpty(), impeller::RoundRect::IsEmpty(), impeller::RoundRect::IsFinite(), impeller::RoundRect::IsOval(), impeller::RoundRect::IsRect(), impeller::TRect< Scalar >::MakeLTRB(), impeller::RoundRect::MakeRect(), impeller::RoundingRadii::top_left, and impeller::RoundingRadii::top_right.

◆ TEST() [361/465]

impeller::testing::TEST ( RoundRectTest  ,
RectRadiiConstructor   
)

Definition at line 506 of file round_rect_unittests.cc.

506  {
507  RoundRect round_rect =
508  RoundRect::MakeRectRadii(Rect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f),
509  {
510  .top_left = Size(1.0, 1.5),
511  .top_right = Size(2.0, 2.5f),
512  .bottom_left = Size(3.0, 3.5f),
513  .bottom_right = Size(4.0, 4.5f),
514  });
515 
516  EXPECT_FALSE(round_rect.IsEmpty());
517  EXPECT_FALSE(round_rect.IsRect());
518  EXPECT_FALSE(round_rect.IsOval());
519  EXPECT_TRUE(round_rect.IsFinite());
520  EXPECT_FALSE(round_rect.GetBounds().IsEmpty());
521  EXPECT_EQ(round_rect.GetBounds(), Rect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f));
522  EXPECT_EQ(round_rect.GetRadii().top_left, Size(1.0f, 1.5f));
523  EXPECT_EQ(round_rect.GetRadii().top_right, Size(2.0f, 2.5f));
524  EXPECT_EQ(round_rect.GetRadii().bottom_left, Size(3.0f, 3.5f));
525  EXPECT_EQ(round_rect.GetRadii().bottom_right, Size(4.0f, 4.5f));
526 }

References impeller::RoundingRadii::bottom_left, impeller::RoundingRadii::bottom_right, impeller::RoundRect::GetBounds(), impeller::RoundRect::GetRadii(), impeller::TRect< T >::IsEmpty(), impeller::RoundRect::IsEmpty(), impeller::RoundRect::IsFinite(), impeller::RoundRect::IsOval(), impeller::RoundRect::IsRect(), impeller::TRect< Scalar >::MakeLTRB(), impeller::RoundRect::MakeRectRadii(), impeller::RoundingRadii::top_left, and impeller::RoundingRadii::top_right.

◆ TEST() [362/465]

impeller::testing::TEST ( RoundRectTest  ,
RectRadiiOverflowHeightConstructor   
)

Definition at line 553 of file round_rect_unittests.cc.

553  {
554  RoundRect round_rect =
555  RoundRect::MakeRectRadii(Rect::MakeXYWH(10.0f, 10.0f, 30.0f, 6.0f),
556  {
557  .top_left = Size(1.0f, 2.0f),
558  .top_right = Size(3.0f, 4.0f),
559  .bottom_left = Size(5.0f, 6.0f),
560  .bottom_right = Size(7.0f, 8.0f),
561  });
562  // Largest sum of paired radii heights is the right edge which sums to 12
563  // Rect is only 6 tall so all radii are scaled by half
564  // Rect is 30 wide so no scaling should happen due to radii widths
565 
566  EXPECT_FALSE(round_rect.IsEmpty());
567  EXPECT_FALSE(round_rect.IsRect());
568  EXPECT_FALSE(round_rect.IsOval());
569  EXPECT_TRUE(round_rect.IsFinite());
570  EXPECT_FALSE(round_rect.GetBounds().IsEmpty());
571  EXPECT_EQ(round_rect.GetBounds(), Rect::MakeLTRB(10.0f, 10.0f, 40.0f, 16.0f));
572  EXPECT_EQ(round_rect.GetRadii().top_left, Size(0.5f, 1.0f));
573  EXPECT_EQ(round_rect.GetRadii().top_right, Size(1.5f, 2.0f));
574  EXPECT_EQ(round_rect.GetRadii().bottom_left, Size(2.5f, 3.0f));
575  EXPECT_EQ(round_rect.GetRadii().bottom_right, Size(3.5f, 4.0f));
576 }

References impeller::RoundingRadii::bottom_left, impeller::RoundingRadii::bottom_right, impeller::RoundRect::GetBounds(), impeller::RoundRect::GetRadii(), impeller::TRect< T >::IsEmpty(), impeller::RoundRect::IsEmpty(), impeller::RoundRect::IsFinite(), impeller::RoundRect::IsOval(), impeller::RoundRect::IsRect(), impeller::TRect< Scalar >::MakeLTRB(), impeller::RoundRect::MakeRectRadii(), impeller::TRect< Scalar >::MakeXYWH(), impeller::RoundingRadii::top_left, and impeller::RoundingRadii::top_right.

◆ TEST() [363/465]

impeller::testing::TEST ( RoundRectTest  ,
RectRadiiOverflowWidthConstructor   
)

Definition at line 528 of file round_rect_unittests.cc.

528  {
529  RoundRect round_rect =
530  RoundRect::MakeRectRadii(Rect::MakeXYWH(10.0f, 10.0f, 6.0f, 30.0f),
531  {
532  .top_left = Size(1.0f, 2.0f),
533  .top_right = Size(3.0f, 4.0f),
534  .bottom_left = Size(5.0f, 6.0f),
535  .bottom_right = Size(7.0f, 8.0f),
536  });
537  // Largest sum of paired radii widths is the bottom edge which sums to 12
538  // Rect is only 6 wide so all radii are scaled by half
539  // Rect is 30 tall so no scaling should happen due to radii heights
540 
541  EXPECT_FALSE(round_rect.IsEmpty());
542  EXPECT_FALSE(round_rect.IsRect());
543  EXPECT_FALSE(round_rect.IsOval());
544  EXPECT_TRUE(round_rect.IsFinite());
545  EXPECT_FALSE(round_rect.GetBounds().IsEmpty());
546  EXPECT_EQ(round_rect.GetBounds(), Rect::MakeLTRB(10.0f, 10.0f, 16.0f, 40.0f));
547  EXPECT_EQ(round_rect.GetRadii().top_left, Size(0.5f, 1.0f));
548  EXPECT_EQ(round_rect.GetRadii().top_right, Size(1.5f, 2.0f));
549  EXPECT_EQ(round_rect.GetRadii().bottom_left, Size(2.5f, 3.0f));
550  EXPECT_EQ(round_rect.GetRadii().bottom_right, Size(3.5f, 4.0f));
551 }

References impeller::RoundingRadii::bottom_left, impeller::RoundingRadii::bottom_right, impeller::RoundRect::GetBounds(), impeller::RoundRect::GetRadii(), impeller::TRect< T >::IsEmpty(), impeller::RoundRect::IsEmpty(), impeller::RoundRect::IsFinite(), impeller::RoundRect::IsOval(), impeller::RoundRect::IsRect(), impeller::TRect< Scalar >::MakeLTRB(), impeller::RoundRect::MakeRectRadii(), impeller::TRect< Scalar >::MakeXYWH(), impeller::RoundingRadii::top_left, and impeller::RoundingRadii::top_right.

◆ TEST() [364/465]

impeller::testing::TEST ( RoundRectTest  ,
RectRadiusConstructor   
)

Definition at line 458 of file round_rect_unittests.cc.

458  {
459  RoundRect round_rect = RoundRect::MakeRectRadius(
460  Rect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f), 2.0f);
461 
462  EXPECT_FALSE(round_rect.IsEmpty());
463  EXPECT_FALSE(round_rect.IsRect());
464  EXPECT_FALSE(round_rect.IsOval());
465  EXPECT_TRUE(round_rect.IsFinite());
466  EXPECT_FALSE(round_rect.GetBounds().IsEmpty());
467  EXPECT_EQ(round_rect.GetBounds(), Rect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f));
468  EXPECT_EQ(round_rect.GetRadii().top_left, Size(2.0f, 2.0f));
469  EXPECT_EQ(round_rect.GetRadii().top_right, Size(2.0f, 2.0f));
470  EXPECT_EQ(round_rect.GetRadii().bottom_left, Size(2.0f, 2.0f));
471  EXPECT_EQ(round_rect.GetRadii().bottom_right, Size(2.0f, 2.0f));
472 }

References impeller::RoundingRadii::bottom_left, impeller::RoundingRadii::bottom_right, impeller::RoundRect::GetBounds(), impeller::RoundRect::GetRadii(), impeller::TRect< T >::IsEmpty(), impeller::RoundRect::IsEmpty(), impeller::RoundRect::IsFinite(), impeller::RoundRect::IsOval(), impeller::RoundRect::IsRect(), impeller::TRect< Scalar >::MakeLTRB(), impeller::RoundRect::MakeRectRadius(), impeller::RoundingRadii::top_left, and impeller::RoundingRadii::top_right.

◆ TEST() [365/465]

impeller::testing::TEST ( RoundRectTest  ,
RectSizeConstructor   
)

Definition at line 490 of file round_rect_unittests.cc.

490  {
491  RoundRect round_rect = RoundRect::MakeRectXY(
492  Rect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f), Size(2.0f, 3.0f));
493 
494  EXPECT_FALSE(round_rect.IsEmpty());
495  EXPECT_FALSE(round_rect.IsRect());
496  EXPECT_FALSE(round_rect.IsOval());
497  EXPECT_TRUE(round_rect.IsFinite());
498  EXPECT_FALSE(round_rect.GetBounds().IsEmpty());
499  EXPECT_EQ(round_rect.GetBounds(), Rect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f));
500  EXPECT_EQ(round_rect.GetRadii().top_left, Size(2.0f, 3.0f));
501  EXPECT_EQ(round_rect.GetRadii().top_right, Size(2.0f, 3.0f));
502  EXPECT_EQ(round_rect.GetRadii().bottom_left, Size(2.0f, 3.0f));
503  EXPECT_EQ(round_rect.GetRadii().bottom_right, Size(2.0f, 3.0f));
504 }

References impeller::RoundingRadii::bottom_left, impeller::RoundingRadii::bottom_right, impeller::RoundRect::GetBounds(), impeller::RoundRect::GetRadii(), impeller::TRect< T >::IsEmpty(), impeller::RoundRect::IsEmpty(), impeller::RoundRect::IsFinite(), impeller::RoundRect::IsOval(), impeller::RoundRect::IsRect(), impeller::TRect< Scalar >::MakeLTRB(), impeller::RoundRect::MakeRectXY(), impeller::RoundingRadii::top_left, and impeller::RoundingRadii::top_right.

◆ TEST() [366/465]

impeller::testing::TEST ( RoundRectTest  ,
RectXYConstructor   
)

Definition at line 474 of file round_rect_unittests.cc.

474  {
475  RoundRect round_rect = RoundRect::MakeRectXY(
476  Rect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f), 2.0f, 3.0f);
477 
478  EXPECT_FALSE(round_rect.IsEmpty());
479  EXPECT_FALSE(round_rect.IsRect());
480  EXPECT_FALSE(round_rect.IsOval());
481  EXPECT_TRUE(round_rect.IsFinite());
482  EXPECT_FALSE(round_rect.GetBounds().IsEmpty());
483  EXPECT_EQ(round_rect.GetBounds(), Rect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f));
484  EXPECT_EQ(round_rect.GetRadii().top_left, Size(2.0f, 3.0f));
485  EXPECT_EQ(round_rect.GetRadii().top_right, Size(2.0f, 3.0f));
486  EXPECT_EQ(round_rect.GetRadii().bottom_left, Size(2.0f, 3.0f));
487  EXPECT_EQ(round_rect.GetRadii().bottom_right, Size(2.0f, 3.0f));
488 }

References impeller::RoundingRadii::bottom_left, impeller::RoundingRadii::bottom_right, impeller::RoundRect::GetBounds(), impeller::RoundRect::GetRadii(), impeller::TRect< T >::IsEmpty(), impeller::RoundRect::IsEmpty(), impeller::RoundRect::IsFinite(), impeller::RoundRect::IsOval(), impeller::RoundRect::IsRect(), impeller::TRect< Scalar >::MakeLTRB(), impeller::RoundRect::MakeRectXY(), impeller::RoundingRadii::top_left, and impeller::RoundingRadii::top_right.

◆ TEST() [367/465]

impeller::testing::TEST ( RoundRectTest  ,
RoundingRadiiCornersSameTolerance   
)

Definition at line 268 of file round_rect_unittests.cc.

268  {
269  RoundingRadii radii{
270  .top_left = {10, 20},
271  .top_right = {10.01, 20.01},
272  .bottom_left = {9.99, 19.99},
273  .bottom_right = {9.99, 20.01},
274  };
275 
276  EXPECT_TRUE(radii.AreAllCornersSame(.02));
277 
278  {
279  RoundingRadii different = radii;
280  different.top_left.width = 10.03;
281  EXPECT_FALSE(different.AreAllCornersSame(.02));
282  }
283  {
284  RoundingRadii different = radii;
285  different.top_left.height = 20.03;
286  EXPECT_FALSE(different.AreAllCornersSame(.02));
287  }
288  {
289  RoundingRadii different = radii;
290  different.top_right.width = 10.03;
291  EXPECT_FALSE(different.AreAllCornersSame(.02));
292  }
293  {
294  RoundingRadii different = radii;
295  different.top_right.height = 20.03;
296  EXPECT_FALSE(different.AreAllCornersSame(.02));
297  }
298  {
299  RoundingRadii different = radii;
300  different.bottom_left.width = 9.97;
301  EXPECT_FALSE(different.AreAllCornersSame(.02));
302  }
303  {
304  RoundingRadii different = radii;
305  different.bottom_left.height = 19.97;
306  EXPECT_FALSE(different.AreAllCornersSame(.02));
307  }
308  {
309  RoundingRadii different = radii;
310  different.bottom_right.width = 9.97;
311  EXPECT_FALSE(different.AreAllCornersSame(.02));
312  }
313  {
314  RoundingRadii different = radii;
315  different.bottom_right.height = 20.03;
316  EXPECT_FALSE(different.AreAllCornersSame(.02));
317  }
318 }

References impeller::RoundingRadii::AreAllCornersSame(), impeller::RoundingRadii::bottom_left, impeller::RoundingRadii::bottom_right, impeller::TSize< T >::height, impeller::RoundingRadii::top_left, impeller::RoundingRadii::top_right, and impeller::TSize< T >::width.

◆ TEST() [368/465]

impeller::testing::TEST ( RoundRectTest  ,
RoundingRadiiDefaultConstructor   
)

Definition at line 34 of file round_rect_unittests.cc.

34  {
35  RoundingRadii radii = RoundingRadii();
36 
37  EXPECT_TRUE(radii.AreAllCornersEmpty());
38  EXPECT_TRUE(radii.AreAllCornersSame());
39  EXPECT_TRUE(radii.IsFinite());
40  EXPECT_EQ(radii.top_left, Size());
41  EXPECT_EQ(radii.top_right, Size());
42  EXPECT_EQ(radii.bottom_left, Size());
43  EXPECT_EQ(radii.bottom_right, Size());
44 }

References impeller::RoundingRadii::AreAllCornersEmpty(), impeller::RoundingRadii::AreAllCornersSame(), impeller::RoundingRadii::bottom_left, impeller::RoundingRadii::bottom_right, impeller::RoundingRadii::IsFinite(), impeller::RoundingRadii::top_left, and impeller::RoundingRadii::top_right.

◆ TEST() [369/465]

impeller::testing::TEST ( RoundRectTest  ,
RoundingRadiiEmptyDeclaration   
)

Definition at line 14 of file round_rect_unittests.cc.

14  {
15  RoundingRadii radii;
16 
17  EXPECT_TRUE(radii.AreAllCornersEmpty());
18  EXPECT_TRUE(radii.AreAllCornersSame());
19  EXPECT_TRUE(radii.IsFinite());
20  EXPECT_EQ(radii.top_left, Size());
21  EXPECT_EQ(radii.top_right, Size());
22  EXPECT_EQ(radii.bottom_left, Size());
23  EXPECT_EQ(radii.bottom_right, Size());
24  EXPECT_EQ(radii.top_left.width, 0.0f);
25  EXPECT_EQ(radii.top_left.height, 0.0f);
26  EXPECT_EQ(radii.top_right.width, 0.0f);
27  EXPECT_EQ(radii.top_right.height, 0.0f);
28  EXPECT_EQ(radii.bottom_left.width, 0.0f);
29  EXPECT_EQ(radii.bottom_left.height, 0.0f);
30  EXPECT_EQ(radii.bottom_right.width, 0.0f);
31  EXPECT_EQ(radii.bottom_right.height, 0.0f);
32 }

References impeller::RoundingRadii::AreAllCornersEmpty(), impeller::RoundingRadii::AreAllCornersSame(), impeller::RoundingRadii::bottom_left, impeller::RoundingRadii::bottom_right, impeller::TSize< T >::height, impeller::RoundingRadii::IsFinite(), impeller::RoundingRadii::top_left, impeller::RoundingRadii::top_right, and impeller::TSize< T >::width.

◆ TEST() [370/465]

impeller::testing::TEST ( RoundRectTest  ,
RoundingRadiiEmptyScalarConstructor   
)

Definition at line 58 of file round_rect_unittests.cc.

58  {
59  RoundingRadii radii = RoundingRadii::MakeRadius(-5.0f);
60 
61  EXPECT_TRUE(radii.AreAllCornersEmpty());
62  EXPECT_TRUE(radii.AreAllCornersSame());
63  EXPECT_TRUE(radii.IsFinite());
64  EXPECT_EQ(radii.top_left, Size(-5.0f, -5.0f));
65  EXPECT_EQ(radii.top_right, Size(-5.0f, -5.0f));
66  EXPECT_EQ(radii.bottom_left, Size(-5.0f, -5.0f));
67  EXPECT_EQ(radii.bottom_right, Size(-5.0f, -5.0f));
68 }

References impeller::RoundingRadii::AreAllCornersEmpty(), impeller::RoundingRadii::AreAllCornersSame(), impeller::RoundingRadii::bottom_left, impeller::RoundingRadii::bottom_right, impeller::RoundingRadii::IsFinite(), impeller::RoundingRadii::MakeRadius(), impeller::RoundingRadii::top_left, and impeller::RoundingRadii::top_right.

◆ TEST() [371/465]

impeller::testing::TEST ( RoundRectTest  ,
RoundingRadiiEmptySizeConstructor   
)

Definition at line 82 of file round_rect_unittests.cc.

82  {
83  {
84  RoundingRadii radii = RoundingRadii::MakeRadii(Size(-5.0f, 6.0f));
85 
86  EXPECT_TRUE(radii.AreAllCornersEmpty());
87  EXPECT_TRUE(radii.AreAllCornersSame());
88  EXPECT_TRUE(radii.IsFinite());
89  EXPECT_EQ(radii.top_left, Size(-5.0f, 6.0f));
90  EXPECT_EQ(radii.top_right, Size(-5.0f, 6.0f));
91  EXPECT_EQ(radii.bottom_left, Size(-5.0f, 6.0f));
92  EXPECT_EQ(radii.bottom_right, Size(-5.0f, 6.0f));
93  }
94 
95  {
96  RoundingRadii radii = RoundingRadii::MakeRadii(Size(5.0f, -6.0f));
97 
98  EXPECT_TRUE(radii.AreAllCornersEmpty());
99  EXPECT_TRUE(radii.AreAllCornersSame());
100  EXPECT_TRUE(radii.IsFinite());
101  EXPECT_EQ(radii.top_left, Size(5.0f, -6.0f));
102  EXPECT_EQ(radii.top_right, Size(5.0f, -6.0f));
103  EXPECT_EQ(radii.bottom_left, Size(5.0f, -6.0f));
104  EXPECT_EQ(radii.bottom_right, Size(5.0f, -6.0f));
105  }
106 }

References impeller::RoundingRadii::AreAllCornersEmpty(), impeller::RoundingRadii::AreAllCornersSame(), impeller::RoundingRadii::bottom_left, impeller::RoundingRadii::bottom_right, impeller::RoundingRadii::IsFinite(), impeller::RoundingRadii::MakeRadii(), impeller::RoundingRadii::top_left, and impeller::RoundingRadii::top_right.

◆ TEST() [372/465]

impeller::testing::TEST ( RoundRectTest  ,
RoundingRadiiEquals   
)

Definition at line 201 of file round_rect_unittests.cc.

201  {
202  RoundingRadii radii = {
203  .top_left = Size(5.0f, 5.5f),
204  .top_right = Size(6.0f, 6.5f),
205  .bottom_left = Size(7.0f, 7.5f),
206  .bottom_right = Size(8.0f, 8.5f),
207  };
208  RoundingRadii other = {
209  .top_left = Size(5.0f, 5.5f),
210  .top_right = Size(6.0f, 6.5f),
211  .bottom_left = Size(7.0f, 7.5f),
212  .bottom_right = Size(8.0f, 8.5f),
213  };
214 
215  EXPECT_EQ(radii, other);
216 }

References impeller::RoundingRadii::top_left.

◆ TEST() [373/465]

impeller::testing::TEST ( RoundRectTest  ,
RoundingRadiiMultiply   
)

Definition at line 183 of file round_rect_unittests.cc.

183  {
184  RoundingRadii radii = {
185  .top_left = Size(5.0f, 5.5f),
186  .top_right = Size(6.0f, 6.5f),
187  .bottom_left = Size(7.0f, 7.5f),
188  .bottom_right = Size(8.0f, 8.5f),
189  };
190  RoundingRadii doubled = radii * 2.0f;
191 
192  EXPECT_FALSE(doubled.AreAllCornersEmpty());
193  EXPECT_FALSE(doubled.AreAllCornersSame());
194  EXPECT_TRUE(doubled.IsFinite());
195  EXPECT_EQ(doubled.top_left, Size(10.0f, 11.0f));
196  EXPECT_EQ(doubled.top_right, Size(12.0f, 13.0f));
197  EXPECT_EQ(doubled.bottom_left, Size(14.0f, 15.0f));
198  EXPECT_EQ(doubled.bottom_right, Size(16.0f, 17.0f));
199 }

References impeller::RoundingRadii::AreAllCornersEmpty(), impeller::RoundingRadii::AreAllCornersSame(), impeller::RoundingRadii::bottom_left, impeller::RoundingRadii::bottom_right, impeller::RoundingRadii::IsFinite(), impeller::RoundingRadii::top_left, and impeller::RoundingRadii::top_right.

◆ TEST() [374/465]

impeller::testing::TEST ( RoundRectTest  ,
RoundingRadiiNamedSizesConstructor   
)

Definition at line 108 of file round_rect_unittests.cc.

108  {
109  RoundingRadii radii = {
110  .top_left = Size(5.0f, 5.5f),
111  .top_right = Size(6.0f, 6.5f),
112  .bottom_left = Size(7.0f, 7.5f),
113  .bottom_right = Size(8.0f, 8.5f),
114  };
115 
116  EXPECT_FALSE(radii.AreAllCornersEmpty());
117  EXPECT_FALSE(radii.AreAllCornersSame());
118  EXPECT_TRUE(radii.IsFinite());
119  EXPECT_EQ(radii.top_left, Size(5.0f, 5.5f));
120  EXPECT_EQ(radii.top_right, Size(6.0f, 6.5f));
121  EXPECT_EQ(radii.bottom_left, Size(7.0f, 7.5f));
122  EXPECT_EQ(radii.bottom_right, Size(8.0f, 8.5f));
123 }

References impeller::RoundingRadii::AreAllCornersEmpty(), impeller::RoundingRadii::AreAllCornersSame(), impeller::RoundingRadii::bottom_left, impeller::RoundingRadii::bottom_right, impeller::RoundingRadii::IsFinite(), impeller::RoundingRadii::top_left, and impeller::RoundingRadii::top_right.

◆ TEST() [375/465]

impeller::testing::TEST ( RoundRectTest  ,
RoundingRadiiNotEquals   
)

Definition at line 218 of file round_rect_unittests.cc.

218  {
219  const RoundingRadii radii = {
220  .top_left = Size(5.0f, 5.5f),
221  .top_right = Size(6.0f, 6.5f),
222  .bottom_left = Size(7.0f, 7.5f),
223  .bottom_right = Size(8.0f, 8.5f),
224  };
225 
226  {
227  RoundingRadii different = radii;
228  different.top_left.width = 100.0f;
229  EXPECT_NE(different, radii);
230  }
231  {
232  RoundingRadii different = radii;
233  different.top_left.height = 100.0f;
234  EXPECT_NE(different, radii);
235  }
236  {
237  RoundingRadii different = radii;
238  different.top_right.width = 100.0f;
239  EXPECT_NE(different, radii);
240  }
241  {
242  RoundingRadii different = radii;
243  different.top_right.height = 100.0f;
244  EXPECT_NE(different, radii);
245  }
246  {
247  RoundingRadii different = radii;
248  different.bottom_left.width = 100.0f;
249  EXPECT_NE(different, radii);
250  }
251  {
252  RoundingRadii different = radii;
253  different.bottom_left.height = 100.0f;
254  EXPECT_NE(different, radii);
255  }
256  {
257  RoundingRadii different = radii;
258  different.bottom_right.width = 100.0f;
259  EXPECT_NE(different, radii);
260  }
261  {
262  RoundingRadii different = radii;
263  different.bottom_right.height = 100.0f;
264  EXPECT_NE(different, radii);
265  }
266 }
Type width
Definition: size.h:28

References impeller::RoundingRadii::bottom_left, impeller::RoundingRadii::bottom_right, impeller::TSize< T >::height, impeller::RoundingRadii::top_left, impeller::RoundingRadii::top_right, and impeller::TSize< T >::width.

◆ TEST() [376/465]

impeller::testing::TEST ( RoundRectTest  ,
RoundingRadiiPartialNamedSizesConstructor   
)

Definition at line 125 of file round_rect_unittests.cc.

125  {
126  {
127  RoundingRadii radii = {
128  .top_left = Size(5.0f, 5.5f),
129  };
130 
131  EXPECT_FALSE(radii.AreAllCornersEmpty());
132  EXPECT_FALSE(radii.AreAllCornersSame());
133  EXPECT_TRUE(radii.IsFinite());
134  EXPECT_EQ(radii.top_left, Size(5.0f, 5.5f));
135  EXPECT_EQ(radii.top_right, Size());
136  EXPECT_EQ(radii.bottom_left, Size());
137  EXPECT_EQ(radii.bottom_right, Size());
138  }
139 
140  {
141  RoundingRadii radii = {
142  .top_right = Size(6.0f, 6.5f),
143  };
144 
145  EXPECT_FALSE(radii.AreAllCornersEmpty());
146  EXPECT_FALSE(radii.AreAllCornersSame());
147  EXPECT_TRUE(radii.IsFinite());
148  EXPECT_EQ(radii.top_left, Size());
149  EXPECT_EQ(radii.top_right, Size(6.0f, 6.5f));
150  EXPECT_EQ(radii.bottom_left, Size());
151  EXPECT_EQ(radii.bottom_right, Size());
152  }
153 
154  {
155  RoundingRadii radii = {
156  .bottom_left = Size(7.0f, 7.5f),
157  };
158 
159  EXPECT_FALSE(radii.AreAllCornersEmpty());
160  EXPECT_FALSE(radii.AreAllCornersSame());
161  EXPECT_TRUE(radii.IsFinite());
162  EXPECT_EQ(radii.top_left, Size());
163  EXPECT_EQ(radii.top_right, Size());
164  EXPECT_EQ(radii.bottom_left, Size(7.0f, 7.5f));
165  EXPECT_EQ(radii.bottom_right, Size());
166  }
167 
168  {
169  RoundingRadii radii = {
170  .bottom_right = Size(8.0f, 8.5f),
171  };
172 
173  EXPECT_FALSE(radii.AreAllCornersEmpty());
174  EXPECT_FALSE(radii.AreAllCornersSame());
175  EXPECT_TRUE(radii.IsFinite());
176  EXPECT_EQ(radii.top_left, Size());
177  EXPECT_EQ(radii.top_right, Size());
178  EXPECT_EQ(radii.bottom_left, Size());
179  EXPECT_EQ(radii.bottom_right, Size(8.0f, 8.5f));
180  }
181 }

References impeller::RoundingRadii::AreAllCornersEmpty(), impeller::RoundingRadii::AreAllCornersSame(), impeller::RoundingRadii::bottom_left, impeller::RoundingRadii::bottom_right, impeller::RoundingRadii::IsFinite(), impeller::RoundingRadii::top_left, and impeller::RoundingRadii::top_right.

◆ TEST() [377/465]

impeller::testing::TEST ( RoundRectTest  ,
RoundingRadiiScalarConstructor   
)

Definition at line 46 of file round_rect_unittests.cc.

46  {
47  RoundingRadii radii = RoundingRadii::MakeRadius(5.0f);
48 
49  EXPECT_FALSE(radii.AreAllCornersEmpty());
50  EXPECT_TRUE(radii.AreAllCornersSame());
51  EXPECT_TRUE(radii.IsFinite());
52  EXPECT_EQ(radii.top_left, Size(5.0f, 5.0f));
53  EXPECT_EQ(radii.top_right, Size(5.0f, 5.0f));
54  EXPECT_EQ(radii.bottom_left, Size(5.0f, 5.0f));
55  EXPECT_EQ(radii.bottom_right, Size(5.0f, 5.0f));
56 }

References impeller::RoundingRadii::AreAllCornersEmpty(), impeller::RoundingRadii::AreAllCornersSame(), impeller::RoundingRadii::bottom_left, impeller::RoundingRadii::bottom_right, impeller::RoundingRadii::IsFinite(), impeller::RoundingRadii::MakeRadius(), impeller::RoundingRadii::top_left, and impeller::RoundingRadii::top_right.

◆ TEST() [378/465]

impeller::testing::TEST ( RoundRectTest  ,
RoundingRadiiSizeConstructor   
)

Definition at line 70 of file round_rect_unittests.cc.

70  {
71  RoundingRadii radii = RoundingRadii::MakeRadii(Size(5.0f, 6.0f));
72 
73  EXPECT_FALSE(radii.AreAllCornersEmpty());
74  EXPECT_TRUE(radii.AreAllCornersSame());
75  EXPECT_TRUE(radii.IsFinite());
76  EXPECT_EQ(radii.top_left, Size(5.0f, 6.0f));
77  EXPECT_EQ(radii.top_right, Size(5.0f, 6.0f));
78  EXPECT_EQ(radii.bottom_left, Size(5.0f, 6.0f));
79  EXPECT_EQ(radii.bottom_right, Size(5.0f, 6.0f));
80 }

References impeller::RoundingRadii::AreAllCornersEmpty(), impeller::RoundingRadii::AreAllCornersSame(), impeller::RoundingRadii::bottom_left, impeller::RoundingRadii::bottom_right, impeller::RoundingRadii::IsFinite(), impeller::RoundingRadii::MakeRadii(), impeller::RoundingRadii::top_left, and impeller::RoundingRadii::top_right.

◆ TEST() [379/465]

impeller::testing::TEST ( RoundRectTest  ,
Shift   
)

Definition at line 578 of file round_rect_unittests.cc.

578  {
579  RoundRect round_rect =
580  RoundRect::MakeRectRadii(Rect::MakeXYWH(10.0f, 10.0f, 30.0f, 30.0f),
581  {
582  .top_left = Size(1.0f, 2.0f),
583  .top_right = Size(3.0f, 4.0f),
584  .bottom_left = Size(5.0f, 6.0f),
585  .bottom_right = Size(7.0f, 8.0f),
586  });
587  RoundRect shifted = round_rect.Shift(5.0, 6.0);
588 
589  EXPECT_FALSE(shifted.IsEmpty());
590  EXPECT_FALSE(shifted.IsRect());
591  EXPECT_FALSE(shifted.IsOval());
592  EXPECT_TRUE(shifted.IsFinite());
593  EXPECT_FALSE(shifted.GetBounds().IsEmpty());
594  EXPECT_EQ(shifted.GetBounds(), Rect::MakeLTRB(15.0f, 16.0f, 45.0f, 46.0f));
595  EXPECT_EQ(shifted.GetRadii().top_left, Size(1.0f, 2.0f));
596  EXPECT_EQ(shifted.GetRadii().top_right, Size(3.0f, 4.0f));
597  EXPECT_EQ(shifted.GetRadii().bottom_left, Size(5.0f, 6.0f));
598  EXPECT_EQ(shifted.GetRadii().bottom_right, Size(7.0f, 8.0f));
599 
600  EXPECT_EQ(shifted,
601  RoundRect::MakeRectRadii(Rect::MakeXYWH(15.0f, 16.0f, 30.0f, 30.0f),
602  {
603  .top_left = Size(1.0f, 2.0f),
604  .top_right = Size(3.0f, 4.0f),
605  .bottom_left = Size(5.0f, 6.0f),
606  .bottom_right = Size(7.0f, 8.0f),
607  }));
608 }

References impeller::TRect< Scalar >::MakeLTRB(), impeller::RoundRect::MakeRectRadii(), impeller::TRect< Scalar >::MakeXYWH(), and impeller::RoundRect::Shift().

◆ TEST() [380/465]

impeller::testing::TEST ( RoundRectTest  ,
TinyCornerRoundRectContains   
)

Definition at line 873 of file round_rect_unittests.cc.

873  {
874  Rect bounds = Rect::MakeLTRB(-50.0f, -50.0f, 50.0f, 50.0f);
875  // RRect of bounds with even the tiniest corners does not contain corners
876  auto tiny_corners = RoundRect::MakeRectXY(bounds, 0.01f, 0.01f);
877 
878  EXPECT_FALSE(tiny_corners.Contains({-50, -50}));
879  EXPECT_FALSE(tiny_corners.Contains({-50, 50}));
880  EXPECT_FALSE(tiny_corners.Contains({50, -50}));
881  EXPECT_FALSE(tiny_corners.Contains({50, 50}));
882 }

References impeller::TRect< Scalar >::MakeLTRB(), and impeller::RoundRect::MakeRectXY().

◆ TEST() [381/465]

impeller::testing::TEST ( RoundRectTest  ,
UniformCircularRoundRectContains   
)

Definition at line 884 of file round_rect_unittests.cc.

884  {
885  Rect bounds = Rect::MakeLTRB(-50.0f, -50.0f, 50.0f, 50.0f);
886  auto expanded_2_r_2 = RoundRect::MakeRectXY(bounds.Expand(2.0), 2.0f, 2.0f);
887 
888  // Expanded by 2.0 and then with a corner of 2.0 obviously still
889  // contains the corners
890  EXPECT_TRUE(expanded_2_r_2.Contains({-50, -50}));
891  EXPECT_TRUE(expanded_2_r_2.Contains({-50, 50}));
892  EXPECT_TRUE(expanded_2_r_2.Contains({50, -50}));
893  EXPECT_TRUE(expanded_2_r_2.Contains({50, 50}));
894 
895  // Now we try to box in the corner containment to exactly where the
896  // rounded corner of the expanded round rect with radii of 2.0 lies.
897  // The 45-degree diagonal point of a circle of radius 2.0 lies at:
898  //
899  // (2 * sqrt(2) / 2, 2 * sqrt(2) / 2)
900  // (sqrt(2), sqrt(2))
901  //
902  // So we test +/- (50 + sqrt(2) +/- epsilon)
903  const auto coord_out = 50 + kSqrt2 + kEhCloseEnough;
904  const auto coord_in = 50 + kSqrt2 - kEhCloseEnough;
905  // Upper left corner
906  EXPECT_TRUE(expanded_2_r_2.Contains({-coord_in, -coord_in}));
907  EXPECT_FALSE(expanded_2_r_2.Contains({-coord_out, -coord_out}));
908  // Upper right corner
909  EXPECT_TRUE(expanded_2_r_2.Contains({coord_in, -coord_in}));
910  EXPECT_FALSE(expanded_2_r_2.Contains({coord_out, -coord_out}));
911  // Lower left corner
912  EXPECT_TRUE(expanded_2_r_2.Contains({-coord_in, coord_in}));
913  EXPECT_FALSE(expanded_2_r_2.Contains({-coord_out, coord_out}));
914  // Lower right corner
915  EXPECT_TRUE(expanded_2_r_2.Contains({coord_in, coord_in}));
916  EXPECT_FALSE(expanded_2_r_2.Contains({coord_out, coord_out}));
917 }

References impeller::TRect< T >::Expand(), impeller::kEhCloseEnough, impeller::kSqrt2, impeller::TRect< Scalar >::MakeLTRB(), and impeller::RoundRect::MakeRectXY().

◆ TEST() [382/465]

impeller::testing::TEST ( RoundRectTest  ,
UniformEllipticalRoundRectContains   
)

Definition at line 919 of file round_rect_unittests.cc.

919  {
920  Rect bounds = Rect::MakeLTRB(-50.0f, -50.0f, 50.0f, 50.0f);
921  auto expanded_2_r_2 = RoundRect::MakeRectXY(bounds.Expand(2.0), 2.0f, 3.0f);
922 
923  // Expanded by 2.0 and then with a corner of 2x3 should still
924  // contain the corners
925  EXPECT_TRUE(expanded_2_r_2.Contains({-50, -50}));
926  EXPECT_TRUE(expanded_2_r_2.Contains({-50, 50}));
927  EXPECT_TRUE(expanded_2_r_2.Contains({50, -50}));
928  EXPECT_TRUE(expanded_2_r_2.Contains({50, 50}));
929 
930  // Now we try to box in the corner containment to exactly where the
931  // rounded corner of the expanded round rect with radii of 2x3 lies.
932  // The "45-degree diagonal point" of an ellipse of radii 2x3 lies at:
933  //
934  // (2 * sqrt(2) / 2, 3 * sqrt(2) / 2)
935  // (sqrt(2), 3 * sqrt(2) / 2)
936  //
937  // And the center(s) of these corners are at:
938  // (+/-(50 + 2 - 2), +/-(50 + 2 - 3))
939  // = (+/-50, +/-49)
940  const auto x_coord_out = 50 + kSqrt2 + kEhCloseEnough;
941  const auto x_coord_in = 50 + kSqrt2 - kEhCloseEnough;
942  const auto y_coord_out = 49 + 3 * kSqrt2 / 2 + kEhCloseEnough;
943  const auto y_coord_in = 49 + 3 * kSqrt2 / 2 - kEhCloseEnough;
944  // Upper left corner
945  EXPECT_TRUE(expanded_2_r_2.Contains({-x_coord_in, -y_coord_in}));
946  EXPECT_FALSE(expanded_2_r_2.Contains({-x_coord_out, -y_coord_out}));
947  // Upper right corner
948  EXPECT_TRUE(expanded_2_r_2.Contains({x_coord_in, -y_coord_in}));
949  EXPECT_FALSE(expanded_2_r_2.Contains({x_coord_out, -y_coord_out}));
950  // Lower left corner
951  EXPECT_TRUE(expanded_2_r_2.Contains({-x_coord_in, y_coord_in}));
952  EXPECT_FALSE(expanded_2_r_2.Contains({-x_coord_out, y_coord_out}));
953  // Lower right corner
954  EXPECT_TRUE(expanded_2_r_2.Contains({x_coord_in, y_coord_in}));
955  EXPECT_FALSE(expanded_2_r_2.Contains({x_coord_out, y_coord_out}));
956 }

References impeller::TRect< T >::Expand(), impeller::kEhCloseEnough, impeller::kSqrt2, impeller::TRect< Scalar >::MakeLTRB(), and impeller::RoundRect::MakeRectXY().

◆ TEST() [383/465]

impeller::testing::TEST ( RSTransformTest  ,
CompareToMatrix   
)

Definition at line 32 of file rstransform_unittests.cc.

32  {
33  for (int tx = 0; tx <= 100; tx += 10) {
34  for (int ty = 0; ty <= 100; ty += 10) {
35  Point origin(tx, ty);
36  for (int scale = 1; scale <= 20; scale += 5) {
37  // Overshoot a full circle by 30 degrees
38  for (int degrees = 0; degrees <= 390; degrees += 45) {
39  auto matrix = Matrix::MakeTranslation(origin) *
40  Matrix::MakeRotationZ(Degrees(degrees)) *
41  Matrix::MakeScale(Vector2(scale, scale));
42  auto rst = RSTransform::Make(origin, scale, Degrees(degrees));
43  EXPECT_MATRIX_NEAR(rst.GetMatrix(), matrix);
44  for (int w = 10; w <= 100; w += 10) {
45  for (int h = 10; h <= 100; h += 10) {
46  Quad q = rst.GetQuad(w, h);
47  auto points = Rect::MakeWH(w, h).GetTransformedPoints(matrix);
48  for (int i = 0; i < 4; i++) {
49  EXPECT_NEAR(q[i].x, points[i].x, kEhCloseEnough);
50  EXPECT_NEAR(q[i].y, points[i].y, kEhCloseEnough);
51  }
52  }
53  }
54  }
55  }
56  }
57  }
58 }
#define EXPECT_MATRIX_NEAR(a, b)

References EXPECT_MATRIX_NEAR, impeller::TRect< T >::GetTransformedPoints(), impeller::kEhCloseEnough, impeller::RSTransform::Make(), impeller::Matrix::MakeRotationZ(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeTranslation(), impeller::TRect< Scalar >::MakeWH(), scale, and x.

◆ TEST() [384/465]

impeller::testing::TEST ( RSTransformTest  ,
Construction   
)

Definition at line 14 of file rstransform_unittests.cc.

14  {
15  RSTransform transform = RSTransform::Make({10.0f, 12.0f}, 2.0f, Degrees(90));
16 
17  EXPECT_EQ(transform.scaled_cos, 0.0f);
18  EXPECT_EQ(transform.scaled_sin, 2.0f);
19  EXPECT_EQ(transform.translate_x, 10.0f);
20  EXPECT_EQ(transform.translate_y, 12.0f);
21 
22  EXPECT_EQ(transform.GetBounds(20.0f, 30.0f),
23  // relative corners are at
24  // 0, 0
25  // 0, 40
26  // -60, 0
27  // -60, 40
28  // then add 10, 12 to all values
29  Rect::MakeLTRB(10 + -2 * 30, 12 + 0, 10 + 0, 12 + 40));
30 }

References impeller::RSTransform::Make(), impeller::TRect< Scalar >::MakeLTRB(), and transform.

◆ TEST() [385/465]

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() [386/465]

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() [387/465]

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() [388/465]

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() [389/465]

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() [390/465]

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() [391/465]

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() [392/465]

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() [393/465]

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() [394/465]

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() [395/465]

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() [396/465]

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() [397/465]

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() [398/465]

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() [399/465]

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() [400/465]

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() [401/465]

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() [402/465]

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() [403/465]

impeller::testing::TEST ( SaveLayerUtilsTest  ,
BackdropFilterEmptyCoverage   
)

Definition at line 163 of file save_layer_utils_unittests.cc.

163  {
164  // Empty coverage with backdrop filter.
165  auto coverage = ComputeSaveLayerCoverage(
166  /*content_coverage=*/Rect::MakeLTRB(0, 0, 0, 0), //
167  /*effect_transform=*/{}, //
168  /*coverage_limit=*/Rect::MakeLTRB(0, 0, 2400, 1800), //
169  /*image_filter=*/nullptr, //
170  /*flood_output_coverage=*/true //
171  );
172 
173  ASSERT_TRUE(coverage.has_value());
174  EXPECT_EQ(coverage.value(), Rect::MakeLTRB(0, 0, 2400, 1800));
175 }
std::optional< Rect > ComputeSaveLayerCoverage(const Rect &content_coverage, const Matrix &effect_transform, const Rect &coverage_limit, const std::shared_ptr< FilterContents > &image_filter, bool flood_output_coverage, bool flood_input_coverage)
Compute the coverage of a subpass in the global coordinate space.

References impeller::ComputeSaveLayerCoverage(), and impeller::TRect< Scalar >::MakeLTRB().

◆ TEST() [404/465]

impeller::testing::TEST ( SaveLayerUtilsTest  ,
BackdropFiterComputedCoverage   
)

Definition at line 29 of file save_layer_utils_unittests.cc.

29  {
30  // Backdrop Filter, computed coverage
31  auto coverage = ComputeSaveLayerCoverage(
32  /*content_coverage=*/Rect::MakeLTRB(0, 0, 10, 10), //
33  /*effect_transform=*/{}, //
34  /*coverage_limit=*/Rect::MakeLTRB(0, 0, 2400, 1800), //
35  /*image_filter=*/nullptr,
36  /*flood_output_coverage=*/false, //
37  /*flood_input_coverage=*/true //
38  );
39 
40  ASSERT_TRUE(coverage.has_value());
41  EXPECT_EQ(coverage.value(), Rect::MakeLTRB(0, 0, 2400, 1800));
42 }

References impeller::ComputeSaveLayerCoverage(), and impeller::TRect< Scalar >::MakeLTRB().

◆ TEST() [405/465]

impeller::testing::TEST ( SaveLayerUtilsTest  ,
BasicEmptyCoverage   
)

Definition at line 137 of file save_layer_utils_unittests.cc.

137  {
138  auto coverage = ComputeSaveLayerCoverage(
139  /*content_coverage=*/Rect::MakeLTRB(0, 0, 0, 0), //
140  /*effect_transform=*/{}, //
141  /*coverage_limit=*/Rect::MakeLTRB(0, 0, 2400, 1800), //
142  /*image_filter=*/nullptr //
143  );
144 
145  ASSERT_FALSE(coverage.has_value());
146 }

References impeller::ComputeSaveLayerCoverage(), and impeller::TRect< Scalar >::MakeLTRB().

◆ TEST() [406/465]

impeller::testing::TEST ( SaveLayerUtilsTest  ,
CoverageLimitIgnoredIfIntersectedValueIsCloseToActualCoverageLargerWithImageFilter   
)

Definition at line 246 of file save_layer_utils_unittests.cc.

248  {
249  // Create an image filter that slightly stretches the coverage limit. Even
250  // without the special logic for using the original content coverage, we
251  // verify that we don't introduce any artifacts from the intersection.
252  auto image_filter = FilterContents::MakeMatrixFilter(
253  FilterInput::Make(Rect()), Matrix::MakeScale({0.9, 0.9, 1}), {});
254 
255  auto coverage = ComputeSaveLayerCoverage(
256  /*content_coverage=*/Rect::MakeLTRB(0, 0, 100, 100), //
257  /*effect_transform=*/{}, //
258  /*coverage_limit=*/Rect::MakeLTRB(0, 0, 100, 100), //
259  /*image_filter=*/image_filter //
260  );
261 
262  ASSERT_TRUE(coverage.has_value());
263  // The transfomed coverage limit is ((0, 0), (111.111, 111.111)).
264  EXPECT_EQ(coverage.value(), Rect::MakeLTRB(0, 0, 100, 100));
265 }

References impeller::ComputeSaveLayerCoverage(), impeller::FilterInput::Make(), impeller::TRect< Scalar >::MakeLTRB(), impeller::FilterContents::MakeMatrixFilter(), and impeller::Matrix::MakeScale().

◆ TEST() [407/465]

impeller::testing::TEST ( SaveLayerUtilsTest  ,
CoverageLimitIgnoredIfIntersectedValueIsCloseToActualCoverageSmallerWithImageFilter   
)

Definition at line 227 of file save_layer_utils_unittests.cc.

229  {
230  // Create an image filter that slightly shrinks the coverage limit
231  auto image_filter = FilterContents::MakeMatrixFilter(
232  FilterInput::Make(Rect()), Matrix::MakeScale({1.1, 1.1, 1}), {});
233 
234  auto coverage = ComputeSaveLayerCoverage(
235  /*content_coverage=*/Rect::MakeLTRB(0, 0, 100, 100), //
236  /*effect_transform=*/{}, //
237  /*coverage_limit=*/Rect::MakeLTRB(0, 0, 100, 100), //
238  /*image_filter=*/image_filter //
239  );
240 
241  ASSERT_TRUE(coverage.has_value());
242  // The transfomed coverage limit is ((0, 0), (90.9091, 90.9091)).
243  EXPECT_EQ(coverage.value(), Rect::MakeLTRB(0, 0, 100, 100));
244 }

References impeller::ComputeSaveLayerCoverage(), impeller::FilterInput::Make(), impeller::TRect< Scalar >::MakeLTRB(), impeller::FilterContents::MakeMatrixFilter(), and impeller::Matrix::MakeScale().

◆ TEST() [408/465]

impeller::testing::TEST ( SaveLayerUtilsTest  ,
CoverageLimitRespectedIfSubstantiallyDifferentFromContentCoverge   
)

Definition at line 267 of file save_layer_utils_unittests.cc.

268  {
269  auto image_filter = FilterContents::MakeMatrixFilter(
270  FilterInput::Make(Rect()), Matrix::MakeScale({2, 2, 1}), {});
271 
272  auto coverage = ComputeSaveLayerCoverage(
273  /*content_coverage=*/Rect::MakeLTRB(0, 0, 1000, 1000), //
274  /*effect_transform=*/{}, //
275  /*coverage_limit=*/Rect::MakeLTRB(0, 0, 100, 100), //
276  /*image_filter=*/image_filter //
277  );
278 
279  ASSERT_TRUE(coverage.has_value());
280  EXPECT_EQ(coverage.value(), Rect::MakeLTRB(0, 0, 50, 50));
281 }

References impeller::ComputeSaveLayerCoverage(), impeller::FilterInput::Make(), impeller::TRect< Scalar >::MakeLTRB(), impeller::FilterContents::MakeMatrixFilter(), and impeller::Matrix::MakeScale().

◆ TEST() [409/465]

impeller::testing::TEST ( SaveLayerUtilsTest  ,
DisjointCoverage   
)

Definition at line 94 of file save_layer_utils_unittests.cc.

94  {
95  // No intersection in coverage
96  auto coverage = ComputeSaveLayerCoverage(
97  /*content_coverage=*/Rect::MakeLTRB(200, 200, 210, 210), //
98  /*effect_transform=*/{}, //
99  /*coverage_limit=*/Rect::MakeLTRB(0, 0, 100, 100), //
100  /*image_filter=*/nullptr //
101  );
102 
103  EXPECT_FALSE(coverage.has_value());
104 }

References impeller::ComputeSaveLayerCoverage(), and impeller::TRect< Scalar >::MakeLTRB().

◆ TEST() [410/465]

impeller::testing::TEST ( SaveLayerUtilsTest  ,
DisjointCoverageTransformedByImageFilter   
)

Definition at line 106 of file save_layer_utils_unittests.cc.

106  {
107  // Coverage disjoint from parent coverage but transformed into parent space
108  // with image filter.
109  auto image_filter = FilterContents::MakeMatrixFilter(
110  FilterInput::Make(Rect()), Matrix::MakeTranslation({-200, -200, 0}), {});
111 
112  auto coverage = ComputeSaveLayerCoverage(
113  /*content_coverage=*/Rect::MakeLTRB(200, 200, 210, 210), //
114  /*effect_transform=*/{}, //
115  /*coverage_limit=*/Rect::MakeLTRB(0, 0, 100, 100), //
116  /*image_filter=*/image_filter //
117  );
118 
119  ASSERT_TRUE(coverage.has_value());
120  EXPECT_EQ(coverage.value(), Rect::MakeLTRB(200, 200, 210, 210));
121 }

References impeller::ComputeSaveLayerCoverage(), impeller::FilterInput::Make(), impeller::TRect< Scalar >::MakeLTRB(), impeller::FilterContents::MakeMatrixFilter(), and impeller::Matrix::MakeTranslation().

◆ TEST() [411/465]

impeller::testing::TEST ( SaveLayerUtilsTest  ,
DisjointCoveragTransformedByCTM   
)

Definition at line 123 of file save_layer_utils_unittests.cc.

123  {
124  // Coverage disjoint from parent coverage.
125  Matrix ctm = Matrix::MakeTranslation({-200, -200, 0});
126  auto coverage = ComputeSaveLayerCoverage(
127  /*content_coverage=*/Rect::MakeLTRB(200, 200, 210, 210), //
128  /*effect_transform=*/ctm, //
129  /*coverage_limit=*/Rect::MakeLTRB(0, 0, 100, 100), //
130  /*image_filter=*/nullptr //
131  );
132 
133  ASSERT_TRUE(coverage.has_value());
134  EXPECT_EQ(coverage.value(), Rect::MakeLTRB(0, 0, 10, 10));
135 }

References impeller::ComputeSaveLayerCoverage(), impeller::TRect< Scalar >::MakeLTRB(), and impeller::Matrix::MakeTranslation().

◆ TEST() [412/465]

impeller::testing::TEST ( SaveLayerUtilsTest  ,
DontRoundUpCoverageWhenNotCloseToCoverageLimitHeight   
)

Definition at line 311 of file save_layer_utils_unittests.cc.

311  {
312  // X varies, translation is performed on coverage.
313  auto coverage = ComputeSaveLayerCoverage(
314  /*content_coverage=*/Rect::MakeLTRB(0, 0, 90, 50), //
315  /*effect_transform=*/{}, //
316  /*coverage_limit=*/Rect::MakeLTRB(0, 0, 100, 100), //
317  /*image_filter=*/nullptr //
318  );
319 
320  ASSERT_TRUE(coverage.has_value());
321  // Size that matches coverage limit
322  EXPECT_EQ(coverage.value(), Rect::MakeLTRB(0, 0, 90, 50));
323 }

References impeller::ComputeSaveLayerCoverage(), and impeller::TRect< Scalar >::MakeLTRB().

◆ TEST() [413/465]

impeller::testing::TEST ( SaveLayerUtilsTest  ,
DontRoundUpCoverageWhenNotCloseToCoverageLimitWidth   
)

Definition at line 297 of file save_layer_utils_unittests.cc.

297  {
298  // X varies, translation is performed on coverage.
299  auto coverage = ComputeSaveLayerCoverage(
300  /*content_coverage=*/Rect::MakeLTRB(0, 0, 50, 90), //
301  /*effect_transform=*/{}, //
302  /*coverage_limit=*/Rect::MakeLTRB(0, 0, 100, 100), //
303  /*image_filter=*/nullptr //
304  );
305 
306  ASSERT_TRUE(coverage.has_value());
307  // Size that matches coverage limit
308  EXPECT_EQ(coverage.value(), Rect::MakeLTRB(0, 0, 50, 90));
309 }

References impeller::ComputeSaveLayerCoverage(), and impeller::TRect< Scalar >::MakeLTRB().

◆ TEST() [414/465]

impeller::testing::TEST ( SaveLayerUtilsTest  ,
DontRoundUpCoverageWhenNotCloseToCoverageLimitWidthHeight   
)

Definition at line 325 of file save_layer_utils_unittests.cc.

326  {
327  // X varies, translation is performed on coverage.
328  auto coverage = ComputeSaveLayerCoverage(
329  /*content_coverage=*/Rect::MakeLTRB(0, 0, 50, 50), //
330  /*effect_transform=*/{}, //
331  /*coverage_limit=*/Rect::MakeLTRB(0, 0, 100, 100), //
332  /*image_filter=*/nullptr //
333  );
334 
335  ASSERT_TRUE(coverage.has_value());
336  // Size that matches coverage limit
337  EXPECT_EQ(coverage.value(), Rect::MakeLTRB(0, 0, 50, 50));
338 }

References impeller::ComputeSaveLayerCoverage(), and impeller::TRect< Scalar >::MakeLTRB().

◆ TEST() [415/465]

impeller::testing::TEST ( SaveLayerUtilsTest  ,
FloodInputCoverage   
)

Definition at line 177 of file save_layer_utils_unittests.cc.

177  {
178  auto coverage = ComputeSaveLayerCoverage(
179  /*content_coverage=*/Rect::MakeLTRB(0, 0, 0, 0), //
180  /*effect_transform=*/{}, //
181  /*coverage_limit=*/Rect::MakeLTRB(0, 0, 2400, 1800), //
182  /*image_filter=*/nullptr, //
183  /*flood_output_coverage=*/false, //
184  /*flood_input_coverage=*/true //
185  );
186 
187  ASSERT_TRUE(coverage.has_value());
188  EXPECT_EQ(coverage.value(), Rect::MakeLTRB(0, 0, 2400, 1800));
189 }

References impeller::ComputeSaveLayerCoverage(), and impeller::TRect< Scalar >::MakeLTRB().

◆ TEST() [416/465]

impeller::testing::TEST ( SaveLayerUtilsTest  ,
FloodInputCoverageWithImageFilter   
)

Definition at line 191 of file save_layer_utils_unittests.cc.

191  {
192  auto image_filter = FilterContents::MakeMatrixFilter(
193  FilterInput::Make(Rect()), Matrix::MakeScale({0.5, 0.5, 1}), {});
194 
195  auto coverage = ComputeSaveLayerCoverage(
196  /*content_coverage=*/Rect::MakeLTRB(0, 0, 0, 0), //
197  /*effect_transform=*/{}, //
198  /*coverage_limit=*/Rect::MakeLTRB(0, 0, 2400, 1800), //
199  /*image_filter=*/image_filter, //
200  /*flood_output_coverage=*/false, //
201  /*flood_input_coverage=*/true //
202  );
203 
204  ASSERT_TRUE(coverage.has_value());
205  EXPECT_EQ(coverage.value(), Rect::MakeLTRB(0, 0, 4800, 3600));
206 }

References impeller::ComputeSaveLayerCoverage(), impeller::FilterInput::Make(), impeller::TRect< Scalar >::MakeLTRB(), impeller::FilterContents::MakeMatrixFilter(), and impeller::Matrix::MakeScale().

◆ TEST() [417/465]

impeller::testing::TEST ( SaveLayerUtilsTest  ,
FloodInputCoverageWithImageFilterWithNoCoverageProducesNoCoverage   
)

Definition at line 208 of file save_layer_utils_unittests.cc.

209  {
210  // Even if we flood the input coverage due to a bdf, we can still cull out the
211  // layer if the image filter results in no coverage.
212  auto image_filter = FilterContents::MakeMatrixFilter(
213  FilterInput::Make(Rect()), Matrix::MakeScale({1, 1, 0}), {});
214 
215  auto coverage = ComputeSaveLayerCoverage(
216  /*content_coverage=*/Rect::MakeLTRB(0, 0, 0, 0), //
217  /*effect_transform=*/{}, //
218  /*coverage_limit=*/Rect::MakeLTRB(0, 0, 2400, 1800), //
219  /*image_filter=*/image_filter, //
220  /*flood_output_coverage=*/false, //
221  /*flood_input_coverage=*/true //
222  );
223 
224  ASSERT_FALSE(coverage.has_value());
225 }

References impeller::ComputeSaveLayerCoverage(), impeller::FilterInput::Make(), impeller::TRect< Scalar >::MakeLTRB(), impeller::FilterContents::MakeMatrixFilter(), and impeller::Matrix::MakeScale().

◆ TEST() [418/465]

impeller::testing::TEST ( SaveLayerUtilsTest  ,
ImageFilterEmptyCoverage   
)

Definition at line 148 of file save_layer_utils_unittests.cc.

148  {
149  // Empty coverage with Image Filter
150  auto image_filter = FilterContents::MakeMatrixFilter(
151  FilterInput::Make(Rect()), Matrix::MakeTranslation({-200, -200, 0}), {});
152 
153  auto coverage = ComputeSaveLayerCoverage(
154  /*content_coverage=*/Rect::MakeLTRB(0, 0, 0, 0), //
155  /*effect_transform=*/{}, //
156  /*coverage_limit=*/Rect::MakeLTRB(0, 0, 2400, 1800), //
157  /*image_filter=*/image_filter //
158  );
159 
160  ASSERT_FALSE(coverage.has_value());
161 }

References impeller::ComputeSaveLayerCoverage(), impeller::FilterInput::Make(), impeller::TRect< Scalar >::MakeLTRB(), impeller::FilterContents::MakeMatrixFilter(), and impeller::Matrix::MakeTranslation().

◆ TEST() [419/465]

impeller::testing::TEST ( SaveLayerUtilsTest  ,
ImageFiterComputedCoverage   
)

Definition at line 44 of file save_layer_utils_unittests.cc.

44  {
45  // Image Filter, computed coverage
46  auto image_filter = FilterContents::MakeMatrixFilter(
47  FilterInput::Make(Rect()), Matrix::MakeScale({2, 2, 1}), {});
48 
49  auto coverage = ComputeSaveLayerCoverage(
50  /*content_coverage=*/Rect::MakeLTRB(0, 0, 10, 10), //
51  /*effect_transform=*/{}, //
52  /*coverage_limit=*/Rect::MakeLTRB(0, 0, 2400, 1800), //
53  /*image_filter=*/image_filter //
54  );
55 
56  ASSERT_TRUE(coverage.has_value());
57  EXPECT_EQ(coverage.value(), Rect::MakeLTRB(0, 0, 10, 10));
58 }

References impeller::ComputeSaveLayerCoverage(), impeller::FilterInput::Make(), impeller::TRect< Scalar >::MakeLTRB(), impeller::FilterContents::MakeMatrixFilter(), and impeller::Matrix::MakeScale().

◆ TEST() [420/465]

impeller::testing::TEST ( SaveLayerUtilsTest  ,
ImageFiterLargeScaleComputedCoverageLargerThanBoundsLimit   
)

Definition at line 77 of file save_layer_utils_unittests.cc.

78  {
79  // Image Filter scaling small, computed coverage is larger than bounds limit.
80  auto image_filter = FilterContents::MakeMatrixFilter(
81  FilterInput::Make(Rect()), Matrix::MakeScale({0.5, 0.5, 1}), {});
82 
83  auto coverage = ComputeSaveLayerCoverage(
84  /*content_coverage=*/Rect::MakeLTRB(0, 0, 10, 10), //
85  /*effect_transform=*/{}, //
86  /*coverage_limit=*/Rect::MakeLTRB(0, 0, 5, 5), //
87  /*image_filter=*/image_filter //
88  );
89 
90  ASSERT_TRUE(coverage.has_value());
91  EXPECT_EQ(coverage.value(), Rect::MakeLTRB(0, 0, 10, 10));
92 }

References impeller::ComputeSaveLayerCoverage(), impeller::FilterInput::Make(), impeller::TRect< Scalar >::MakeLTRB(), impeller::FilterContents::MakeMatrixFilter(), and impeller::Matrix::MakeScale().

◆ TEST() [421/465]

impeller::testing::TEST ( SaveLayerUtilsTest  ,
ImageFiterSmallScaleComputedCoverageLargerThanBoundsLimit   
)

Definition at line 60 of file save_layer_utils_unittests.cc.

61  {
62  // Image Filter scaling large, computed coverage is larger than bounds limit.
63  auto image_filter = FilterContents::MakeMatrixFilter(
64  FilterInput::Make(Rect()), Matrix::MakeScale({2, 2, 1}), {});
65 
66  auto coverage = ComputeSaveLayerCoverage(
67  /*content_coverage=*/Rect::MakeLTRB(0, 0, 10, 10), //
68  /*effect_transform=*/{}, //
69  /*coverage_limit=*/Rect::MakeLTRB(0, 0, 5, 5), //
70  /*image_filter=*/image_filter //
71  );
72 
73  ASSERT_TRUE(coverage.has_value());
74  EXPECT_EQ(coverage.value(), Rect::MakeLTRB(0, 0, 2.5, 2.5));
75 }

References impeller::ComputeSaveLayerCoverage(), impeller::FilterInput::Make(), impeller::TRect< Scalar >::MakeLTRB(), impeller::FilterContents::MakeMatrixFilter(), and impeller::Matrix::MakeScale().

◆ TEST() [422/465]

impeller::testing::TEST ( SaveLayerUtilsTest  ,
RoundUpCoverageWhenCloseToCoverageLimit   
)

Definition at line 283 of file save_layer_utils_unittests.cc.

283  {
284  // X varies, translation is performed on coverage.
285  auto coverage = ComputeSaveLayerCoverage(
286  /*content_coverage=*/Rect::MakeLTRB(0, 0, 90, 90), //
287  /*effect_transform=*/{}, //
288  /*coverage_limit=*/Rect::MakeLTRB(0, 0, 100, 100), //
289  /*image_filter=*/nullptr //
290  );
291 
292  ASSERT_TRUE(coverage.has_value());
293  // Size that matches coverage limit
294  EXPECT_EQ(coverage.value(), Rect::MakeLTRB(0, 0, 100, 100));
295 }

References impeller::ComputeSaveLayerCoverage(), and impeller::TRect< Scalar >::MakeLTRB().

◆ TEST() [423/465]

impeller::testing::TEST ( SaveLayerUtilsTest  ,
SimplePaintComputedCoverage   
)

Definition at line 17 of file save_layer_utils_unittests.cc.

17  {
18  // Basic Case, simple paint, computed coverage
19  auto coverage = ComputeSaveLayerCoverage(
20  /*content_coverage=*/Rect::MakeLTRB(0, 0, 10, 10), //
21  /*effect_transform=*/{}, //
22  /*coverage_limit=*/Rect::MakeLTRB(0, 0, 2400, 1800), //
23  /*image_filter=*/nullptr //
24  );
25  ASSERT_TRUE(coverage.has_value());
26  EXPECT_EQ(coverage.value(), Rect::MakeLTRB(0, 0, 10, 10));
27 }

References impeller::ComputeSaveLayerCoverage(), and impeller::TRect< Scalar >::MakeLTRB().

◆ TEST() [424/465]

impeller::testing::TEST ( ShaderArchiveTest  ,
CanReadAndWriteBlobs   
)

Definition at line 28 of file shader_archive_unittests.cc.

28  {
29  ShaderArchiveWriter writer;
30  ASSERT_TRUE(writer.AddShader(ArchiveShaderType::kVertex, "Hello",
31  CreateMappingFromString("World")));
32  ASSERT_TRUE(writer.AddShader(ArchiveShaderType::kFragment, "Foo",
33  CreateMappingFromString("Bar")));
34  ASSERT_TRUE(writer.AddShader(ArchiveShaderType::kVertex, "Baz",
35  CreateMappingFromString("Bang")));
36  ASSERT_TRUE(writer.AddShader(ArchiveShaderType::kVertex, "Ping",
37  CreateMappingFromString("Pong")));
38  ASSERT_TRUE(writer.AddShader(ArchiveShaderType::kFragment, "Pang",
39  CreateMappingFromString("World")));
40 
41  auto mapping = writer.CreateMapping();
42  ASSERT_NE(mapping, nullptr);
43 
44  ShaderArchive library(mapping);
45  ASSERT_TRUE(library.IsValid());
46  ASSERT_EQ(library.GetShaderCount(), 5u);
47 
48  // Wrong type.
49  ASSERT_EQ(library.GetMapping(ArchiveShaderType::kFragment, "Hello"), nullptr);
50 
51  auto hello_vtx = library.GetMapping(ArchiveShaderType::kVertex, "Hello");
52  ASSERT_NE(hello_vtx, nullptr);
53  ASSERT_EQ(CreateStringFromMapping(*hello_vtx), "World");
54 }
const std::string CreateStringFromMapping(const fml::Mapping &mapping)
static std::shared_ptr< fml::Mapping > CreateMappingFromString(std::string p_string)

References impeller::ShaderArchiveWriter::AddShader(), impeller::ShaderArchiveWriter::CreateMapping(), CreateMappingFromString(), CreateStringFromMapping(), impeller::ShaderArchive::GetMapping(), impeller::ShaderArchive::GetShaderCount(), impeller::ShaderArchive::IsValid(), impeller::kFragment, and impeller::kVertex.

◆ TEST() [425/465]

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() [426/465]

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() [427/465]

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() [428/465]

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() [429/465]

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() [430/465]

impeller::testing::TEST ( SkiaConversionsTest  ,
BlendMode   
)

Definition at line 297 of file skia_conversions_unittests.cc.

297  {
298  for (auto i = 0; i < static_cast<int>(flutter::DlBlendMode::kLastMode); i++) {
299  EXPECT_EQ(
300  skia_conversions::ToBlendMode(static_cast<flutter::DlBlendMode>(i)),
301  static_cast<BlendMode>(i));
302  }
303 }
BlendMode ToBlendMode(flutter::DlBlendMode mode)

References impeller::skia_conversions::ToBlendMode().

◆ TEST() [431/465]

impeller::testing::TEST ( SkiaConversionsTest  ,
GradientConversionNonMonotonic   
)

Definition at line 234 of file skia_conversions_unittests.cc.

234  {
235  std::vector<flutter::DlColor> colors = {
236  flutter::DlColor::kBlue(), flutter::DlColor::kGreen(),
237  flutter::DlColor::kGreen(), flutter::DlColor::kRed()};
238  std::vector<float> stops = {0.0, 0.5, 0.4, 1.0};
239  const auto gradient =
240  flutter::DlColorSource::MakeLinear(flutter::DlPoint(0, 0), //
241  flutter::DlPoint(1.0, 1.0), //
242  4, //
243  colors.data(), //
244  stops.data(), //
245  flutter::DlTileMode::kClamp, //
246  nullptr //
247  );
248 
249  std::vector<Color> converted_colors;
250  std::vector<Scalar> converted_stops;
251  skia_conversions::ConvertStops(gradient->asLinearGradient(), converted_colors,
252  converted_stops);
253 
254  // Value is clamped to 0.5
255  ASSERT_TRUE(ScalarNearlyEqual(converted_stops[0], 0.0f));
256  ASSERT_TRUE(ScalarNearlyEqual(converted_stops[1], 0.5f));
257  ASSERT_TRUE(ScalarNearlyEqual(converted_stops[2], 0.5f));
258  ASSERT_TRUE(ScalarNearlyEqual(converted_stops[3], 1.0f));
259 }
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...
flutter::DlPoint DlPoint
Definition: dl_dispatcher.h:24

References impeller::skia_conversions::ConvertStops(), and impeller::ScalarNearlyEqual().

◆ TEST() [432/465]

impeller::testing::TEST ( SkiaConversionsTest  ,
GradientMissing0   
)

Definition at line 156 of file skia_conversions_unittests.cc.

156  {
157  std::vector<flutter::DlColor> colors = {flutter::DlColor::kBlue(),
158  flutter::DlColor::kRed()};
159  std::vector<float> stops = {0.5, 1.0};
160  const auto gradient =
161  flutter::DlColorSource::MakeLinear(flutter::DlPoint(0, 0), //
162  flutter::DlPoint(1.0, 1.0), //
163  2, //
164  colors.data(), //
165  stops.data(), //
166  flutter::DlTileMode::kClamp, //
167  nullptr //
168  );
169 
170  std::vector<Color> converted_colors;
171  std::vector<Scalar> converted_stops;
172  skia_conversions::ConvertStops(gradient->asLinearGradient(), converted_colors,
173  converted_stops);
174 
175  // First color is inserted as blue.
176  ASSERT_TRUE(ScalarNearlyEqual(converted_colors[0].blue, 1.0f));
177  ASSERT_TRUE(ScalarNearlyEqual(converted_stops[0], 0.0f));
178  ASSERT_TRUE(ScalarNearlyEqual(converted_stops[1], 0.5f));
179  ASSERT_TRUE(ScalarNearlyEqual(converted_stops[2], 1.0f));
180 }

References impeller::skia_conversions::ConvertStops(), and impeller::ScalarNearlyEqual().

◆ TEST() [433/465]

impeller::testing::TEST ( SkiaConversionsTest  ,
GradientMissingLastValue   
)

Definition at line 182 of file skia_conversions_unittests.cc.

182  {
183  std::vector<flutter::DlColor> colors = {flutter::DlColor::kBlue(),
184  flutter::DlColor::kRed()};
185  std::vector<float> stops = {0.0, .5};
186  const auto gradient =
187  flutter::DlColorSource::MakeLinear(flutter::DlPoint(0, 0), //
188  flutter::DlPoint(1.0, 1.0), //
189  2, //
190  colors.data(), //
191  stops.data(), //
192  flutter::DlTileMode::kClamp, //
193  nullptr //
194  );
195 
196  std::vector<Color> converted_colors;
197  std::vector<Scalar> converted_stops;
198  skia_conversions::ConvertStops(gradient->asLinearGradient(), converted_colors,
199  converted_stops);
200 
201  // Last color is inserted as red.
202  ASSERT_TRUE(ScalarNearlyEqual(converted_colors[2].red, 1.0f));
203  ASSERT_TRUE(ScalarNearlyEqual(converted_stops[0], 0.0f));
204  ASSERT_TRUE(ScalarNearlyEqual(converted_stops[1], 0.5f));
205  ASSERT_TRUE(ScalarNearlyEqual(converted_stops[2], 1.0f));
206 }

References impeller::skia_conversions::ConvertStops(), and impeller::ScalarNearlyEqual().

◆ TEST() [434/465]

impeller::testing::TEST ( SkiaConversionsTest  ,
GradientStopConversion   
)

Definition at line 130 of file skia_conversions_unittests.cc.

130  {
131  // Typical gradient.
132  std::vector<flutter::DlColor> colors = {flutter::DlColor::kBlue(),
133  flutter::DlColor::kRed(),
134  flutter::DlColor::kGreen()};
135  std::vector<float> stops = {0.0, 0.5, 1.0};
136  const auto gradient =
137  flutter::DlColorSource::MakeLinear(flutter::DlPoint(0, 0), //
138  flutter::DlPoint(1.0, 1.0), //
139  3, //
140  colors.data(), //
141  stops.data(), //
142  flutter::DlTileMode::kClamp, //
143  nullptr //
144  );
145 
146  std::vector<Color> converted_colors;
147  std::vector<Scalar> converted_stops;
148  skia_conversions::ConvertStops(gradient->asLinearGradient(), converted_colors,
149  converted_stops);
150 
151  ASSERT_TRUE(ScalarNearlyEqual(converted_stops[0], 0.0f));
152  ASSERT_TRUE(ScalarNearlyEqual(converted_stops[1], 0.5f));
153  ASSERT_TRUE(ScalarNearlyEqual(converted_stops[2], 1.0f));
154 }

References impeller::skia_conversions::ConvertStops(), and impeller::ScalarNearlyEqual().

◆ TEST() [435/465]

impeller::testing::TEST ( SkiaConversionsTest  ,
GradientStopGreaterThan1   
)

Definition at line 208 of file skia_conversions_unittests.cc.

208  {
209  std::vector<flutter::DlColor> colors = {flutter::DlColor::kBlue(),
210  flutter::DlColor::kGreen(),
211  flutter::DlColor::kRed()};
212  std::vector<float> stops = {0.0, 100, 1.0};
213  const auto gradient =
214  flutter::DlColorSource::MakeLinear(flutter::DlPoint(0, 0), //
215  flutter::DlPoint(1.0, 1.0), //
216  3, //
217  colors.data(), //
218  stops.data(), //
219  flutter::DlTileMode::kClamp, //
220  nullptr //
221  );
222 
223  std::vector<Color> converted_colors;
224  std::vector<Scalar> converted_stops;
225  skia_conversions::ConvertStops(gradient->asLinearGradient(), converted_colors,
226  converted_stops);
227 
228  // Value is clamped to 1.0
229  ASSERT_TRUE(ScalarNearlyEqual(converted_stops[0], 0.0f));
230  ASSERT_TRUE(ScalarNearlyEqual(converted_stops[1], 1.0f));
231  ASSERT_TRUE(ScalarNearlyEqual(converted_stops[2], 1.0f));
232 }

References impeller::skia_conversions::ConvertStops(), and impeller::ScalarNearlyEqual().

◆ TEST() [436/465]

impeller::testing::TEST ( SkiaConversionsTest  ,
IsNearlySimpleRRect   
)

Definition at line 261 of file skia_conversions_unittests.cc.

261  {
263  SkRRect::MakeRectXY(SkRect::MakeLTRB(0, 0, 10, 10), 10, 10)));
265  SkRRect::MakeRectXY(SkRect::MakeLTRB(0, 0, 10, 10), 10, 9.999)));
267  SkRRect::MakeRectXY(SkRect::MakeLTRB(0, 0, 10, 10), 10, 9)));
269  SkRRect::MakeRectXY(SkRect::MakeLTRB(0, 0, 10, 10), 10, 5)));
270  SkRect rect = SkRect::MakeLTRB(0, 0, 10, 10);
271  SkRRect rrect;
272  union {
273  SkPoint radii[4] = {
274  {10.0f, 9.0f},
275  {10.0f, 9.0f},
276  {10.0f, 9.0f},
277  {10.0f, 9.0f},
278  };
279  SkScalar values[8];
280  } test;
281  rrect.setRectRadii(rect, test.radii);
282  EXPECT_TRUE(skia_conversions::IsNearlySimpleRRect(rrect));
283  for (int i = 0; i < 8; i++) {
284  auto save = test.values[i];
285  test.values[i] -= kEhCloseEnough * 0.5f;
286  rrect.setRectRadii(rect, test.radii);
287  EXPECT_TRUE(skia_conversions::IsNearlySimpleRRect(rrect))
288  << "values[" << i << "] == " << test.values[i];
289  test.values[i] -= kEhCloseEnough * 2.0f;
290  rrect.setRectRadii(rect, test.radii);
291  EXPECT_FALSE(skia_conversions::IsNearlySimpleRRect(rrect))
292  << "values[" << i << "] == " << test.values[i];
293  test.values[i] = save;
294  }
295 }
bool IsNearlySimpleRRect(const SkRRect &rr)
Like SkRRect.isSimple, but allows the corners to differ by kEhCloseEnough.

References impeller::skia_conversions::IsNearlySimpleRRect(), and impeller::kEhCloseEnough.

◆ TEST() [437/465]

impeller::testing::TEST ( SkiaConversionsTest  ,
SkPointToPoint   
)

Definition at line 98 of file skia_conversions_unittests.cc.

98  {
99  for (int x = -100; x < 100; x += 4) {
100  for (int y = -100; y < 100; y += 4) {
101  EXPECT_EQ(skia_conversions::ToPoint(SkPoint::Make(x * 0.25f, y * 0.25f)),
102  Point(x * 0.25f, y * 0.25f));
103  }
104  }
105 }
Point ToPoint(const SkPoint &point)

References impeller::skia_conversions::ToPoint(), and x.

◆ TEST() [438/465]

impeller::testing::TEST ( SkiaConversionsTest  ,
SkPointToSize   
)

Definition at line 107 of file skia_conversions_unittests.cc.

107  {
108  for (int x = -100; x < 100; x += 4) {
109  for (int y = -100; y < 100; y += 4) {
110  EXPECT_EQ(skia_conversions::ToSize(SkPoint::Make(x * 0.25f, y * 0.25f)),
111  Size(x * 0.25f, y * 0.25f));
112  }
113  }
114 }
Size ToSize(const SkPoint &point)

References impeller::skia_conversions::ToSize(), and x.

◆ TEST() [439/465]

impeller::testing::TEST ( SkiaConversionsTest  ,
ToColor   
)

Definition at line 116 of file skia_conversions_unittests.cc.

116  {
117  // Create a color with alpha, red, green, and blue values that are all
118  // trivially divisible by 255 so that we can test the conversion results in
119  // correct scalar values.
120  // AARRGGBB
121  const flutter::DlColor color = flutter::DlColor(0x8040C020);
122  auto converted_color = skia_conversions::ToColor(color);
123 
124  ASSERT_TRUE(ScalarNearlyEqual(converted_color.alpha, 0x80 * (1.0f / 255)));
125  ASSERT_TRUE(ScalarNearlyEqual(converted_color.red, 0x40 * (1.0f / 255)));
126  ASSERT_TRUE(ScalarNearlyEqual(converted_color.green, 0xC0 * (1.0f / 255)));
127  ASSERT_TRUE(ScalarNearlyEqual(converted_color.blue, 0x20 * (1.0f / 255)));
128 }
Color ToColor(const flutter::DlColor &color)

References impeller::ScalarNearlyEqual(), and impeller::skia_conversions::ToColor().

◆ TEST() [440/465]

impeller::testing::TEST ( SkiaConversionTest  ,
ToMatrixRotate   
)

Definition at line 47 of file skia_conversions_unittests.cc.

47  {
48  SkMatrix sk_matrix = SkMatrix::RotateDeg(90);
49  Matrix matrix = skia_conversions::ToMatrix(sk_matrix);
50 
51  EXPECT_EQ(matrix.vec[0], Vector4(0, 1, 0, 0));
52  EXPECT_EQ(matrix.vec[1], Vector4(-1, 0, 0, 0));
53  EXPECT_EQ(matrix.vec[2], Vector4(0, 0, 1, 0));
54  EXPECT_EQ(matrix.vec[3], Vector4(0, 0, 0, 1));
55  EXPECT_FALSE(matrix.IsTranslationScaleOnly());
56 }
Matrix ToMatrix(const SkMatrix &m)

References impeller::Matrix::IsTranslationScaleOnly(), impeller::skia_conversions::ToMatrix(), and impeller::Matrix::vec.

◆ TEST() [441/465]

impeller::testing::TEST ( SkiaConversionTest  ,
ToMatrixScale   
)

Definition at line 33 of file skia_conversions_unittests.cc.

33  {
34  SkMatrix sk_matrix = SkMatrix::Scale(2, 2);
35  Matrix matrix = skia_conversions::ToMatrix(sk_matrix);
36 
37  EXPECT_EQ(matrix.m[0], 2);
38  EXPECT_EQ(matrix.m[5], 2);
39  EXPECT_TRUE(matrix.IsTranslationScaleOnly());
40 
41  matrix.m[0] = 1;
42  matrix.m[5] = 1;
43 
44  EXPECT_TRUE(matrix.IsIdentity());
45 }

References impeller::Matrix::IsIdentity(), impeller::Matrix::IsTranslationScaleOnly(), impeller::Matrix::m, and impeller::skia_conversions::ToMatrix().

◆ TEST() [442/465]

impeller::testing::TEST ( SkiaConversionTest  ,
ToMatrixSkew   
)

Definition at line 58 of file skia_conversions_unittests.cc.

58  {
59  SkMatrix sk_matrix = SkMatrix::Skew(2, 2);
60  Matrix matrix = skia_conversions::ToMatrix(sk_matrix);
61 
62  EXPECT_EQ(matrix.vec[0], Vector4(1, 2, 0, 0));
63  EXPECT_EQ(matrix.vec[1], Vector4(2, 1, 0, 0));
64  EXPECT_EQ(matrix.vec[2], Vector4(0, 0, 1, 0));
65  EXPECT_EQ(matrix.vec[3], Vector4(0, 0, 0, 1));
66  EXPECT_FALSE(matrix.IsTranslationScaleOnly());
67 }

References impeller::Matrix::IsTranslationScaleOnly(), impeller::skia_conversions::ToMatrix(), and impeller::Matrix::vec.

◆ TEST() [443/465]

impeller::testing::TEST ( SkiaConversionTest  ,
ToMatrixTranslate   
)

Definition at line 19 of file skia_conversions_unittests.cc.

19  {
20  SkMatrix sk_matrix = SkMatrix::Translate(100, 100);
21  Matrix matrix = skia_conversions::ToMatrix(sk_matrix);
22 
23  EXPECT_EQ(matrix.m[12], 100);
24  EXPECT_EQ(matrix.m[13], 100);
25  EXPECT_TRUE(matrix.IsTranslationScaleOnly());
26 
27  matrix.m[12] = 0;
28  matrix.m[13] = 0;
29 
30  EXPECT_TRUE(matrix.IsIdentity());
31 }

References impeller::Matrix::IsIdentity(), impeller::Matrix::IsTranslationScaleOnly(), impeller::Matrix::m, and impeller::skia_conversions::ToMatrix().

◆ TEST() [444/465]

impeller::testing::TEST ( SkiaConversionTest  ,
ToSamplerDescriptor   
)

Definition at line 69 of file skia_conversions_unittests.cc.

69  {
71  flutter::DlImageSampling::kNearestNeighbor)
72  .min_filter,
75  flutter::DlImageSampling::kNearestNeighbor)
76  .mip_filter,
78 
79  EXPECT_EQ(
80  skia_conversions::ToSamplerDescriptor(flutter::DlImageSampling::kLinear)
81  .min_filter,
83  EXPECT_EQ(
84  skia_conversions::ToSamplerDescriptor(flutter::DlImageSampling::kLinear)
85  .mip_filter,
87 
89  flutter::DlImageSampling::kMipmapLinear)
90  .min_filter,
93  flutter::DlImageSampling::kMipmapLinear)
94  .mip_filter,
96 }
@ kLinear
Sample from the two nearest mip levels and linearly interpolate.
@ kBase
The texture is sampled as if it only had a single mipmap level.
static impeller::SamplerDescriptor ToSamplerDescriptor(const flutter::DlFilterMode options)
@ kNearest
Select nearest to the sample point. Most widely supported.

References impeller::kBase, impeller::kLinear, impeller::kNearest, and impeller::skia_conversions::ToSamplerDescriptor().

◆ TEST() [445/465]

impeller::testing::TEST ( StringsTest  ,
CanSPrintF   
)

Definition at line 84 of file base_unittests.cc.

84  {
85  ASSERT_EQ(SPrintF("%sx%d", "Hello", 12), "Hellox12");
86  ASSERT_EQ(SPrintF(""), "");
87  ASSERT_EQ(SPrintF("Hello"), "Hello");
88  ASSERT_EQ(SPrintF("%sx%.2f", "Hello", 12.122222), "Hellox12.12");
89 }
std::string SPrintF(const char *format,...)
Definition: strings.cc:12

References impeller::SPrintF().

◆ TEST() [446/465]

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() [447/465]

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() [448/465]

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() [449/465]

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() [450/465]

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() [451/465]

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() [452/465]

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() [453/465]

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() [454/465]

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() [455/465]

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() [456/465]

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() [457/465]

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 }
std::shared_ptr< TextureMTL > CreateTextureFromDrawableFuture(TextureDescriptor desc, const std::shared_future< id< CAMetalDrawable >> &drawble_future)
Create a TextureMTL from a deferred drawable.
constexpr MTLPixelFormat ToMTLPixelFormat(PixelFormat format)
Definition: formats_mtl.h:76
std::shared_future< id< CAMetalDrawable > > GetDrawableDeferred(CAMetalLayer *layer)
Create a deferred drawable from a CAMetalLayer.

References impeller::CreateTextureFromDrawableFuture(), impeller::TextureDescriptor::format, impeller::GetDrawableDeferred(), impeller::kB8G8R8A8UNormInt, impeller::TextureDescriptor::size, and impeller::ToMTLPixelFormat().

◆ TEST() [458/465]

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() [459/465]

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() [460/465]

impeller::testing::TEST ( ThreadTest  ,
CanCreateRWMutex   
)

Definition at line 53 of file base_unittests.cc.

53  {
54  RWFoo f = {};
55 
56  // f.a = 100; <--- Static analysis error.
57  f.mtx.LockWriter();
58  f.a = 100;
59  f.mtx.UnlockWriter();
60  // int b = f.a; <--- Static analysis error.
61  f.mtx.LockReader();
62  [[maybe_unused]] int b = f.a; // NOLINT(clang-analyzer-deadcode.DeadStores)
63  f.mtx.UnlockReader();
64 }

References impeller::saturated::b, and impeller::testing::RWFoo::mtx.

◆ TEST() [461/465]

impeller::testing::TEST ( ThreadTest  ,
CanCreateRWMutexLock   
)

Definition at line 66 of file base_unittests.cc.

66  {
67  RWFoo f = {};
68 
69  // f.a = 100; <--- Static analysis error.
70  {
71  auto write_lock = WriterLock{f.mtx};
72  f.a = 100;
73  }
74 
75  // int b = f.a; <--- Static analysis error.
76  {
77  auto read_lock = ReaderLock(f.mtx);
78  [[maybe_unused]] int b = f.a; // NOLINT(clang-analyzer-deadcode.DeadStores)
79  }
80 
81  // f.mtx.UnlockReader(); <--- Static analysis error.
82 }

References impeller::saturated::b, and impeller::testing::RWFoo::mtx.

◆ TEST() [462/465]

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() [463/465]

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() [464/465]

impeller::testing::TEST ( TypographerTest  ,
RectanglePackerFillsRows   
)

Definition at line 404 of file typographer_unittests.cc.

404  {
405  auto skyline = RectanglePacker::Factory(257, 256);
406 
407  // Fill up the first row.
408  IPoint16 loc;
409  for (auto i = 0u; i < 16; i++) {
410  skyline->AddRect(16, 16, &loc);
411  }
412  // Last rectangle still in first row.
413  EXPECT_EQ(loc.x(), 256 - 16);
414  EXPECT_EQ(loc.y(), 0);
415 
416  // Fill up second row.
417  for (auto i = 0u; i < 16; i++) {
418  skyline->AddRect(16, 16, &loc);
419  }
420 
421  EXPECT_EQ(loc.x(), 256 - 16);
422  EXPECT_EQ(loc.y(), 16);
423 }

References impeller::RectanglePacker::Factory(), impeller::IPoint16::x(), and impeller::IPoint16::y().

◆ TEST() [465/465]

impeller::testing::TEST ( UniqueHandleGLES  ,
MakeUntracked   
)

Definition at line 26 of file unique_handle_gles_unittests.cc.

26  {
27  auto mock_gles_impl = std::make_unique<MockGLESImpl>();
28 
29  EXPECT_CALL(*mock_gles_impl, GenTextures(1, _)).Times(1);
30 
31  std::shared_ptr<MockGLES> mock_gled =
32  MockGLES::Init(std::move(mock_gles_impl));
33  ProcTableGLES::Resolver resolver = kMockResolverGLES;
34  auto proc_table = std::make_unique<ProcTableGLES>(resolver);
35  auto worker = std::make_shared<TestWorker>();
36  auto reactor = std::make_shared<ReactorGLES>(std::move(proc_table));
37  reactor->AddWorker(worker);
38 
39  UniqueHandleGLES handle =
40  UniqueHandleGLES::MakeUntracked(reactor, HandleType::kTexture);
41  EXPECT_FALSE(handle.Get().IsDead());
42 }

References impeller::UniqueHandleGLES::Get(), impeller::HandleGLES::IsDead(), impeller::kTexture, and impeller::UniqueHandleGLES::MakeUntracked().

◆ TEST_F()

impeller::testing::TEST_F ( GoldenTests  ,
ConicalGradient   
)

Definition at line 76 of file golden_tests.cc.

76  {
77  flutter::DisplayListBuilder builder;
78  flutter::DlPaint paint;
79  paint.setDrawStyle(flutter::DlDrawStyle::kFill);
80 
81  flutter::DlColor colors[2] = {flutter::DlColor::RGBA(1, 0, 0, 1),
82  flutter::DlColor::RGBA(0, 0, 1, 1)};
83  Scalar stops[2] = {0, 1};
84 
85  paint.setColorSource(flutter::DlColorSource::MakeConical(
86  /*start_center=*/{125, 125}, //
87  /*start_radius=*/125, {180, 180}, //
88  /*end_radius=*/0, //
89  /*stop_count=*/2, //
90  /*colors=*/colors, //
91  /*stops=*/stops, //
92  /*tile_mode=*/flutter::DlTileMode::kClamp //
93  ));
94 
95  builder.DrawRect(SkRect::MakeXYWH(10, 10, 250, 250), paint);
96 
97  auto aiks_context =
98  AiksContext(Screenshotter().GetPlayground().GetContext(), nullptr);
99  auto screenshot = Screenshotter().MakeScreenshot(
100  aiks_context,
101  DisplayListToTexture(builder.Build(), {240, 240}, aiks_context));
102  ASSERT_TRUE(SaveScreenshot(std::move(screenshot)));
103 }
std::shared_ptr< Texture > DisplayListToTexture(const sk_sp< flutter::DisplayList > &display_list, ISize size, AiksContext &context, bool reset_host_buffer, bool generate_mips)
Render the provided display list to a texture with the given size.

References impeller::DisplayListToTexture(), and impeller::testing::Screenshotter::MakeScreenshot().

◆ TEST_P() [1/497]

impeller::testing::TEST_P ( AiksTest  ,
AdvancedBlendColorFilterWithDestinationOpacity   
)

Definition at line 909 of file aiks_dl_blend_unittests.cc.

909  {
910  DisplayListBuilder builder;
911 
912  builder.DrawPaint(DlPaint(DlColor::kWhite()));
913 
914  DlPaint save_paint;
915  save_paint.setOpacity(0.3);
916  save_paint.setColorFilter(DlColorFilter::MakeBlend(DlColor::kTransparent(),
917  DlBlendMode::kSaturation));
918  builder.SaveLayer(nullptr, &save_paint);
919  builder.DrawRect(SkRect::MakeXYWH(100, 100, 300, 300),
920  DlPaint(DlColor::kMaroon()));
921  builder.DrawRect(SkRect::MakeXYWH(200, 200, 300, 300),
922  DlPaint(DlColor::kBlue()));
923  builder.Restore();
924 
925  // Should be solid red as the destructive color filter floods the clip.
926  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
927 }

◆ TEST_P() [2/497]

impeller::testing::TEST_P ( AiksTest  ,
ArcWithZeroSweepAndBlur   
)

Definition at line 429 of file aiks_dl_path_unittests.cc.

429  {
430  DisplayListBuilder builder;
431  builder.Scale(GetContentScale().x, GetContentScale().y);
432 
433  DlPaint paint;
434  paint.setColor(DlColor::kRed());
435 
436  std::vector<DlColor> colors = {DlColor::RGBA(1.0, 0.0, 0.0, 1.0),
437  DlColor::RGBA(0.0, 0.0, 0.0, 1.0)};
438  std::vector<Scalar> stops = {0.0, 1.0};
439 
440  paint.setColorSource(
441  DlColorSource::MakeSweep({100, 100}, 45, 135, stops.size(), colors.data(),
442  stops.data(), DlTileMode::kMirror));
443  paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kNormal, 20));
444 
445  SkPath path;
446  path.addArc(SkRect::MakeXYWH(10, 10, 100, 100), 0, 0);
447  builder.DrawPath(path, paint);
448 
449  // Check that this empty picture can be created without crashing.
450  builder.Build();
451 }

References x.

◆ TEST_P() [3/497]

impeller::testing::TEST_P ( AiksTest  ,
BackdropCountDownBackdropId   
)

Definition at line 174 of file canvas_unittests.cc.

174  {
175  ContentContext context(GetContext(), nullptr);
176  if (!context.GetDeviceCapabilities().SupportsFramebufferFetch()) {
177  GTEST_SKIP() << "Test requires device with framebuffer fetch";
178  }
179  auto canvas = CreateTestCanvas(context, Rect::MakeLTRB(0, 0, 100, 100),
180  /*requires_readback=*/true);
181  // 3 backdrop filters all with same id.
182  std::unordered_map<int64_t, BackdropData> data;
183  data[1] = BackdropData{.backdrop_count = 3};
184  canvas->SetBackdropData(data, 3);
185 
186  auto blur =
187  flutter::DlImageFilter::MakeBlur(4, 4, flutter::DlTileMode::kClamp);
188 
189  EXPECT_TRUE(canvas->RequiresReadback());
190  canvas->DrawRect(flutter::DlRect::MakeLTRB(0, 0, 50, 50),
191  {.color = Color::Azure()});
192  canvas->SaveLayer({}, std::nullopt, blur.get(),
193  ContentBoundsPromise::kContainsContents,
194  /*total_content_depth=*/1, /*can_distribute_opacity=*/false,
195  /*backdrop_id=*/1);
196  canvas->Restore();
197  EXPECT_FALSE(canvas->RequiresReadback());
198 
199  canvas->SaveLayer({}, std::nullopt, blur.get(),
200  ContentBoundsPromise::kContainsContents,
201  /*total_content_depth=*/1, /*can_distribute_opacity=*/false,
202  /*backdrop_id=*/1);
203  canvas->Restore();
204  EXPECT_FALSE(canvas->RequiresReadback());
205 
206  canvas->SaveLayer({}, std::nullopt, blur.get(),
207  ContentBoundsPromise::kContainsContents,
208  /*total_content_depth=*/1, /*can_distribute_opacity=*/false,
209  /*backdrop_id=*/1);
210  canvas->Restore();
211  EXPECT_FALSE(canvas->RequiresReadback());
212 }
std::unique_ptr< Canvas > CreateTestCanvas(ContentContext &context, std::optional< Rect > cull_rect=std::nullopt, bool requires_readback=false)

References impeller::Color::Azure(), impeller::BackdropData::backdrop_count, CreateTestCanvas(), data, impeller::ContentContext::GetDeviceCapabilities(), impeller::kContainsContents, impeller::TRect< Scalar >::MakeLTRB(), and impeller::Capabilities::SupportsFramebufferFetch().

◆ TEST_P() [4/497]

impeller::testing::TEST_P ( AiksTest  ,
BackdropCountDownBackdropIdMixed   
)

Definition at line 214 of file canvas_unittests.cc.

214  {
215  ContentContext context(GetContext(), nullptr);
216  if (!context.GetDeviceCapabilities().SupportsFramebufferFetch()) {
217  GTEST_SKIP() << "Test requires device with framebuffer fetch";
218  }
219  auto canvas = CreateTestCanvas(context, Rect::MakeLTRB(0, 0, 100, 100),
220  /*requires_readback=*/true);
221  // 3 backdrop filters, 2 with same id.
222  std::unordered_map<int64_t, BackdropData> data;
223  data[1] = BackdropData{.backdrop_count = 2};
224  canvas->SetBackdropData(data, 3);
225 
226  auto blur =
227  flutter::DlImageFilter::MakeBlur(4, 4, flutter::DlTileMode::kClamp);
228 
229  EXPECT_TRUE(canvas->RequiresReadback());
230  canvas->DrawRect(flutter::DlRect::MakeLTRB(0, 0, 50, 50),
231  {.color = Color::Azure()});
232  canvas->SaveLayer({}, std::nullopt, blur.get(),
233  ContentBoundsPromise::kContainsContents, 1, false);
234  canvas->Restore();
235  EXPECT_TRUE(canvas->RequiresReadback());
236 
237  canvas->SaveLayer({}, std::nullopt, blur.get(),
238  ContentBoundsPromise::kContainsContents, 1, false, 1);
239  canvas->Restore();
240  EXPECT_FALSE(canvas->RequiresReadback());
241 
242  canvas->SaveLayer({}, std::nullopt, blur.get(),
243  ContentBoundsPromise::kContainsContents, 1, false, 1);
244  canvas->Restore();
245  EXPECT_FALSE(canvas->RequiresReadback());
246 }

References impeller::Color::Azure(), impeller::BackdropData::backdrop_count, CreateTestCanvas(), data, impeller::ContentContext::GetDeviceCapabilities(), impeller::kContainsContents, impeller::TRect< Scalar >::MakeLTRB(), and impeller::Capabilities::SupportsFramebufferFetch().

◆ TEST_P() [5/497]

impeller::testing::TEST_P ( AiksTest  ,
BackdropCountDownNormal   
)

Definition at line 139 of file canvas_unittests.cc.

139  {
140  ContentContext context(GetContext(), nullptr);
141  if (!context.GetDeviceCapabilities().SupportsFramebufferFetch()) {
142  GTEST_SKIP() << "Test requires device with framebuffer fetch";
143  }
144  auto canvas = CreateTestCanvas(context, Rect::MakeLTRB(0, 0, 100, 100),
145  /*requires_readback=*/true);
146  // 3 backdrop filters
147  canvas->SetBackdropData({}, 3);
148 
149  auto blur =
150  flutter::DlImageFilter::MakeBlur(4, 4, flutter::DlTileMode::kClamp);
151  flutter::DlRect rect = flutter::DlRect::MakeLTRB(0, 0, 50, 50);
152 
153  EXPECT_TRUE(canvas->RequiresReadback());
154  canvas->DrawRect(rect, {.color = Color::Azure()});
155  canvas->SaveLayer({}, rect, blur.get(),
156  ContentBoundsPromise::kContainsContents,
157  /*total_content_depth=*/1);
158  canvas->Restore();
159  EXPECT_TRUE(canvas->RequiresReadback());
160 
161  canvas->SaveLayer({}, rect, blur.get(),
162  ContentBoundsPromise::kContainsContents,
163  /*total_content_depth=*/1);
164  canvas->Restore();
165  EXPECT_TRUE(canvas->RequiresReadback());
166 
167  canvas->SaveLayer({}, rect, blur.get(),
168  ContentBoundsPromise::kContainsContents,
169  /*total_content_depth=*/1);
170  canvas->Restore();
171  EXPECT_FALSE(canvas->RequiresReadback());
172 }
flutter::DlRect DlRect
Definition: dl_dispatcher.h:25

References impeller::Color::Azure(), CreateTestCanvas(), impeller::ContentContext::GetDeviceCapabilities(), impeller::kContainsContents, impeller::TRect< Scalar >::MakeLTRB(), and impeller::Capabilities::SupportsFramebufferFetch().

◆ TEST_P() [6/497]

impeller::testing::TEST_P ( AiksTest  ,
BackdropCountDownWithNestedSaveLayers   
)

Definition at line 251 of file canvas_unittests.cc.

251  {
252  ContentContext context(GetContext(), nullptr);
253  if (!context.GetDeviceCapabilities().SupportsFramebufferFetch()) {
254  GTEST_SKIP() << "Test requires device with framebuffer fetch";
255  }
256  auto canvas = CreateTestCanvas(context, Rect::MakeLTRB(0, 0, 100, 100),
257  /*requires_readback=*/true);
258 
259  canvas->SetBackdropData({}, 2);
260 
261  auto blur =
262  flutter::DlImageFilter::MakeBlur(4, 4, flutter::DlTileMode::kClamp);
263 
264  EXPECT_TRUE(canvas->RequiresReadback());
265  canvas->DrawRect(flutter::DlRect::MakeLTRB(0, 0, 50, 50),
266  {.color = Color::Azure()});
267  canvas->SaveLayer({}, std::nullopt, blur.get(),
268  ContentBoundsPromise::kContainsContents,
269  /*total_content_depth=*/3);
270 
271  // This filter is nested in the first saveLayer. We cannot restore to onscreen
272  // here.
273  canvas->SaveLayer({}, std::nullopt, blur.get(),
274  ContentBoundsPromise::kContainsContents,
275  /*total_content_depth=*/1);
276  canvas->Restore();
277  EXPECT_TRUE(canvas->RequiresReadback());
278 
279  canvas->Restore();
280  EXPECT_TRUE(canvas->RequiresReadback());
281 }

References impeller::Color::Azure(), CreateTestCanvas(), impeller::ContentContext::GetDeviceCapabilities(), impeller::kContainsContents, impeller::TRect< Scalar >::MakeLTRB(), and impeller::Capabilities::SupportsFramebufferFetch().

◆ TEST_P() [7/497]

impeller::testing::TEST_P ( AiksTest  ,
BackdropFilterOverUnclosedClip   
)

Definition at line 1594 of file aiks_dl_basic_unittests.cc.

1594  {
1595  DisplayListBuilder builder;
1596 
1597  builder.DrawPaint(DlPaint().setColor(DlColor::kWhite()));
1598  builder.Save();
1599  {
1600  builder.ClipRect(DlRect::MakeLTRB(100, 100, 800, 800));
1601 
1602  builder.Save();
1603  {
1604  builder.ClipRect(DlRect::MakeLTRB(600, 600, 800, 800));
1605  builder.DrawPaint(DlPaint().setColor(DlColor::kRed()));
1606  builder.DrawPaint(DlPaint().setColor(DlColor::kBlue().withAlphaF(0.5)));
1607  builder.ClipRect(DlRect::MakeLTRB(700, 700, 750, 800));
1608  builder.DrawPaint(DlPaint().setColor(DlColor::kRed().withAlphaF(0.5)));
1609  }
1610  builder.Restore();
1611 
1612  auto image_filter = DlImageFilter::MakeBlur(10, 10, DlTileMode::kDecal);
1613  builder.SaveLayer(std::nullopt, nullptr, image_filter.get());
1614  }
1615  builder.Restore();
1616  builder.DrawCircle(SkPoint{100, 100}, 100,
1617  DlPaint().setColor(DlColor::kAqua()));
1618 
1619  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1620 }

◆ TEST_P() [8/497]

impeller::testing::TEST_P ( AiksTest  ,
BackdropRestoreUsesCorrectCoverageForFirstRestoredClip   
)

Definition at line 912 of file aiks_dl_unittests.cc.

912  {
913  DisplayListBuilder builder;
914 
915  DlPaint paint;
916  // Add a difference clip that cuts out the bottom right corner
917  builder.ClipRect(SkRect::MakeLTRB(50, 50, 100, 100),
918  DlCanvas::ClipOp::kDifference);
919 
920  // Draw a red rectangle that's going to be completely covered by green later.
921  paint.setColor(DlColor::kRed());
922  builder.DrawRect(SkRect::MakeLTRB(0, 0, 100, 100), paint);
923 
924  // Add a clip restricting the backdrop filter to the top right corner.
925  auto count = builder.GetSaveCount();
926  builder.Save();
927  {
928  builder.ClipRect(SkRect::MakeLTRB(0, 0, 100, 100));
929  {
930  // Create a save layer with a backdrop blur filter.
931  auto backdrop_filter =
932  DlImageFilter::MakeBlur(10.0, 10.0, DlTileMode::kDecal);
933  builder.SaveLayer(nullptr, nullptr, backdrop_filter.get());
934  }
935  }
936  builder.RestoreToCount(count);
937 
938  // Finally, overwrite all the previous stuff with green.
939  paint.setColor(DlColor::kGreen());
940  builder.DrawRect(SkRect::MakeLTRB(0, 0, 100, 100), paint);
941 
942  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
943 }

◆ TEST_P() [9/497]

impeller::testing::TEST_P ( AiksTest  ,
BlendModePlusAlphaColorFilterWideGamut   
)

Definition at line 433 of file aiks_dl_blend_unittests.cc.

433  {
434  EXPECT_EQ(GetContext()->GetCapabilities()->GetDefaultColorFormat(),
435  PixelFormat::kB10G10R10A10XR);
436  auto texture = CreateTextureForFixture("airplane.jpg",
437  /*enable_mipmapping=*/true);
438 
439  DisplayListBuilder builder;
440  builder.Scale(GetContentScale().x, GetContentScale().y);
441 
442  DlPaint paint;
443  paint.setColor(DlColor::RGBA(0.1, 0.2, 0.1, 1.0));
444  builder.DrawPaint(paint);
445 
446  DlPaint save_paint;
447  save_paint.setColorFilter(
448  DlColorFilter::MakeBlend(DlColor::RGBA(1, 0, 0, 1), DlBlendMode::kPlus));
449  builder.SaveLayer(nullptr, &save_paint);
450 
451  paint.setColor(DlColor::kRed());
452  builder.DrawRect(SkRect::MakeXYWH(100, 100, 400, 400), paint);
453 
454  paint.setColor(DlColor::kWhite());
455 
456  auto rect = Rect::MakeXYWH(100, 100, 400, 400).Expand(-100, -100);
457  builder.DrawImageRect(
458  DlImageImpeller::Make(texture),
459  SkRect::MakeSize(
460  SkSize::Make(texture->GetSize().width, texture->GetSize().height)),
461  SkRect::MakeLTRB(rect.GetLeft(), rect.GetTop(), rect.GetRight(),
462  rect.GetBottom()),
463  DlImageSampling::kMipmapLinear, &paint);
464  builder.Restore();
465 
466  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
467 }

References impeller::TRect< T >::Expand(), impeller::kB10G10R10A10XR, impeller::DlImageImpeller::Make(), impeller::TRect< Scalar >::MakeXYWH(), and x.

◆ TEST_P() [10/497]

impeller::testing::TEST_P ( AiksTest  ,
BlendModePlusAlphaWideGamut   
)

Definition at line 400 of file aiks_dl_blend_unittests.cc.

400  {
401  EXPECT_EQ(GetContext()->GetCapabilities()->GetDefaultColorFormat(),
402  PixelFormat::kB10G10R10A10XR);
403  auto texture = CreateTextureForFixture("airplane.jpg",
404  /*enable_mipmapping=*/true);
405 
406  DisplayListBuilder builder;
407  DlPaint paint;
408  builder.Scale(GetContentScale().x, GetContentScale().y);
409 
410  paint.setColor(DlColor::RGBA(0.9, 1, 0.9, 1.0));
411  builder.DrawPaint(paint);
412  builder.SaveLayer(nullptr);
413 
414  paint.setBlendMode(DlBlendMode::kPlus);
415  paint.setColor(DlColor::kRed());
416 
417  builder.DrawRect(SkRect::MakeXYWH(100, 100, 400, 400), paint);
418  paint.setColor(DlColor::kWhite());
419 
420  auto rect = Rect::MakeXYWH(100, 100, 400, 400).Expand(-100, -100);
421  builder.DrawImageRect(
422  DlImageImpeller::Make(texture),
423  SkRect::MakeSize(
424  SkSize::Make(texture->GetSize().width, texture->GetSize().height)),
425  SkRect::MakeLTRB(rect.GetLeft(), rect.GetTop(), rect.GetRight(),
426  rect.GetBottom()),
427  DlImageSampling::kMipmapLinear, &paint);
428  builder.Restore();
429  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
430 }

References impeller::TRect< T >::Expand(), impeller::kB10G10R10A10XR, impeller::DlImageImpeller::Make(), impeller::TRect< Scalar >::MakeXYWH(), and x.

◆ TEST_P() [11/497]

impeller::testing::TEST_P ( AiksTest  ,
BlendModeShouldCoverWholeScreen   
)

Definition at line 83 of file aiks_dl_blend_unittests.cc.

83  {
84  DisplayListBuilder builder;
85  DlPaint paint;
86 
87  paint.setColor(DlColor::kRed());
88  builder.DrawPaint(paint);
89 
90  paint.setBlendMode(DlBlendMode::kSrcOver);
91  builder.SaveLayer(nullptr, &paint);
92 
93  paint.setColor(DlColor::kWhite());
94  builder.DrawRect(SkRect::MakeXYWH(100, 100, 400, 400), paint);
95 
96  paint.setBlendMode(DlBlendMode::kSrc);
97  builder.SaveLayer(nullptr, &paint);
98 
99  paint.setColor(DlColor::kBlue());
100  builder.DrawRect(SkRect::MakeXYWH(200, 200, 200, 200), paint);
101 
102  builder.Restore();
103  builder.Restore();
104 
105  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
106 }

◆ TEST_P() [12/497]

impeller::testing::TEST_P ( AiksTest  ,
BlurHasNoEdge   
)

Definition at line 439 of file aiks_dl_blur_unittests.cc.

439  {
440  Scalar sigma = 47.6;
441  auto callback = [&]() -> sk_sp<DisplayList> {
442  if (AiksTest::ImGuiBegin("Controls", nullptr,
443  ImGuiWindowFlags_AlwaysAutoResize)) {
444  ImGui::SliderFloat("Sigma", &sigma, 0, 50);
445  ImGui::End();
446  }
447  DisplayListBuilder builder;
448  builder.Scale(GetContentScale().x, GetContentScale().y);
449  builder.DrawPaint({});
450 
451  DlPaint paint;
452  paint.setColor(DlColor::kGreen());
453  paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kNormal, sigma));
454 
455  builder.DrawRect(SkRect::MakeXYWH(300, 300, 200, 200), paint);
456  return builder.Build();
457  };
458 
459  ASSERT_TRUE(OpenPlaygroundHere(callback));
460 }

References impeller::AiksPlayground::ImGuiBegin(), and x.

◆ TEST_P() [13/497]

impeller::testing::TEST_P ( AiksTest  ,
BlurredRectangleWithShader   
)

Definition at line 1199 of file aiks_dl_blur_unittests.cc.

1199  {
1200  DisplayListBuilder builder;
1201  builder.Scale(GetContentScale().x, GetContentScale().y);
1202 
1203  auto paint_lines = [&builder](Scalar dx, Scalar dy, DlPaint paint) {
1204  auto draw_line = [&builder, &paint](SkPoint a, SkPoint b) {
1205  SkPath line = SkPath::Line(a, b);
1206  builder.DrawPath(line, paint);
1207  };
1208  paint.setStrokeWidth(5);
1209  paint.setDrawStyle(DlDrawStyle::kStroke);
1210  draw_line(SkPoint::Make(dx + 100, dy + 100),
1211  SkPoint::Make(dx + 200, dy + 200));
1212  draw_line(SkPoint::Make(dx + 100, dy + 200),
1213  SkPoint::Make(dx + 200, dy + 100));
1214  draw_line(SkPoint::Make(dx + 150, dy + 100),
1215  SkPoint::Make(dx + 200, dy + 150));
1216  draw_line(SkPoint::Make(dx + 100, dy + 150),
1217  SkPoint::Make(dx + 150, dy + 200));
1218  };
1219 
1220  AiksContext renderer(GetContext(), nullptr);
1221  DisplayListBuilder recorder_builder;
1222  for (int x = 0; x < 5; ++x) {
1223  for (int y = 0; y < 5; ++y) {
1224  SkRect rect = SkRect::MakeXYWH(x * 20, y * 20, 20, 20);
1225  DlPaint paint;
1226  paint.setColor(((x + y) & 1) == 0 ? DlColor::kYellow()
1227  : DlColor::kBlue());
1228 
1229  recorder_builder.DrawRect(rect, paint);
1230  }
1231  }
1232  auto texture =
1233  DisplayListToTexture(recorder_builder.Build(), {100, 100}, renderer);
1234 
1235  auto image_source = DlColorSource::MakeImage(
1236  DlImageImpeller::Make(texture), DlTileMode::kRepeat, DlTileMode::kRepeat);
1237  auto blur_filter = DlImageFilter::MakeBlur(5, 5, DlTileMode::kDecal);
1238 
1239  DlPaint paint;
1240  paint.setColor(DlColor::kDarkGreen());
1241  builder.DrawRect(SkRect::MakeLTRB(0, 0, 300, 600), paint);
1242 
1243  paint.setColorSource(image_source);
1244  builder.DrawRect(SkRect::MakeLTRB(100, 100, 200, 200), paint);
1245 
1246  paint.setColorSource(nullptr);
1247  paint.setColor(DlColor::kRed());
1248  builder.DrawRect(SkRect::MakeLTRB(300, 0, 600, 600), paint);
1249 
1250  paint.setColorSource(image_source);
1251  paint.setImageFilter(blur_filter);
1252  builder.DrawRect(SkRect::MakeLTRB(400, 100, 500, 200), paint);
1253 
1254  paint.setImageFilter(nullptr);
1255  paint_lines(0, 300, paint);
1256 
1257  paint.setImageFilter(blur_filter);
1258  paint_lines(300, 300, paint);
1259 
1260  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1261 }

References impeller::saturated::b, impeller::DisplayListToTexture(), impeller::DlImageImpeller::Make(), and x.

◆ TEST_P() [14/497]

impeller::testing::TEST_P ( AiksTest  ,
CanConvertTriangleFanToTriangles   
)

Definition at line 156 of file aiks_dl_vertices_unittests.cc.

156  {
157  constexpr Scalar hexagon_radius = 125;
158  auto hex_start = Point(200.0, -hexagon_radius + 200.0);
159  auto center_to_flat = 1.73 / 2 * hexagon_radius;
160 
161  // clang-format off
162  std::vector<DlPoint> vertices = {
163  DlPoint(hex_start.x, hex_start.y),
164  DlPoint(hex_start.x + center_to_flat, hex_start.y + 0.5 * hexagon_radius),
165  DlPoint(hex_start.x + center_to_flat, hex_start.y + 1.5 * hexagon_radius),
166  DlPoint(hex_start.x + center_to_flat, hex_start.y + 1.5 * hexagon_radius),
167  DlPoint(hex_start.x, hex_start.y + 2 * hexagon_radius),
168  DlPoint(hex_start.x, hex_start.y + 2 * hexagon_radius),
169  DlPoint(hex_start.x - center_to_flat, hex_start.y + 1.5 * hexagon_radius),
170  DlPoint(hex_start.x - center_to_flat, hex_start.y + 1.5 * hexagon_radius),
171  DlPoint(hex_start.x - center_to_flat, hex_start.y + 0.5 * hexagon_radius)
172  };
173  // clang-format on
174  auto paint = flutter::DlPaint(flutter::DlColor::kDarkGrey());
175  auto dl_vertices = flutter::DlVertices::Make(
176  flutter::DlVertexMode::kTriangleFan, vertices.size(), vertices.data(),
177  nullptr, nullptr);
178  flutter::DisplayListBuilder builder;
179  builder.DrawVertices(dl_vertices, flutter::DlBlendMode::kSrcOver, paint);
180  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
181 }

◆ TEST_P() [15/497]

impeller::testing::TEST_P ( AiksTest  ,
CanDrawAnOpenPath   
)

Definition at line 181 of file aiks_dl_path_unittests.cc.

181  {
182  DisplayListBuilder builder;
183 
184  // Starting at (50, 50), draw lines from:
185  // 1. (50, height)
186  // 2. (width, height)
187  // 3. (width, 50)
188  SkPath path;
189  path.moveTo(50, 50);
190  path.lineTo(50, 100);
191  path.lineTo(100, 100);
192  path.lineTo(100, 50);
193 
194  DlPaint paint;
195  paint.setColor(DlColor::kRed());
196  paint.setDrawStyle(DlDrawStyle::kStroke);
197  paint.setStrokeWidth(10);
198 
199  builder.DrawPath(path, paint);
200 
201  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
202 }

◆ TEST_P() [16/497]

impeller::testing::TEST_P ( AiksTest  ,
CanDrawAnOpenPathThatIsntARect   
)

Definition at line 204 of file aiks_dl_path_unittests.cc.

204  {
205  DisplayListBuilder builder;
206 
207  // Draw a stroked path that is explicitly closed to verify
208  // It doesn't become a rectangle.
209  SkPath path;
210  // PathBuilder builder;
211  path.moveTo(50, 50);
212  path.lineTo(520, 120);
213  path.lineTo(300, 310);
214  path.lineTo(100, 50);
215  path.close();
216 
217  DlPaint paint;
218  paint.setColor(DlColor::kRed());
219  paint.setDrawStyle(DlDrawStyle::kStroke);
220  paint.setStrokeWidth(10);
221 
222  builder.DrawPath(path, paint);
223 
224  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
225 }

◆ TEST_P() [17/497]

impeller::testing::TEST_P ( AiksTest  ,
CanDrawMultiContourConvexPath   
)

Definition at line 407 of file aiks_dl_path_unittests.cc.

407  {
408  SkPath path;
409  for (auto i = 0; i < 10; i++) {
410  if (i % 2 == 0) {
411  path.addCircle(100 + 50 * i, 100 + 50 * i, 100);
412  path.close();
413  } else {
414  path.moveTo({100.f + 50.f * i - 100, 100.f + 50.f * i});
415  path.lineTo({100.f + 50.f * i, 100.f + 50.f * i - 100});
416  path.lineTo({100.f + 50.f * i - 100, 100.f + 50.f * i - 100});
417  path.close();
418  }
419  }
420 
421  DisplayListBuilder builder;
422  DlPaint paint;
423  paint.setColor(DlColor::kRed().withAlpha(102));
424  builder.DrawPath(path, paint);
425 
426  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
427 }

◆ TEST_P() [18/497]

impeller::testing::TEST_P ( AiksTest  ,
CanDrawPaint   
)

Definition at line 410 of file aiks_dl_basic_unittests.cc.

410  {
411  auto medium_turquoise =
412  DlColor::RGBA(72.0f / 255.0f, 209.0f / 255.0f, 204.0f / 255.0f, 1.0f);
413 
414  DisplayListBuilder builder;
415  builder.Scale(0.2, 0.2);
416  builder.DrawPaint(DlPaint().setColor(medium_turquoise));
417  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
418 }

◆ TEST_P() [19/497]

impeller::testing::TEST_P ( AiksTest  ,
CanDrawPaintMultipleTimes   
)

Definition at line 420 of file aiks_dl_basic_unittests.cc.

420  {
421  auto medium_turquoise =
422  DlColor::RGBA(72.0f / 255.0f, 209.0f / 255.0f, 204.0f / 255.0f, 1.0f);
423  auto orange_red =
424  DlColor::RGBA(255.0f / 255.0f, 69.0f / 255.0f, 0.0f / 255.0f, 1.0f);
425 
426  DisplayListBuilder builder;
427  builder.Scale(0.2, 0.2);
428  builder.DrawPaint(DlPaint().setColor(medium_turquoise));
429  builder.DrawPaint(DlPaint().setColor(orange_red.modulateOpacity(0.5f)));
430  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
431 }

◆ TEST_P() [20/497]

impeller::testing::TEST_P ( AiksTest  ,
CanDrawPaintMultipleTimesInteractive   
)

Definition at line 684 of file aiks_dl_blend_unittests.cc.

684  {
685  auto modes = GetBlendModeSelection();
686 
687  auto callback = [&]() -> sk_sp<DisplayList> {
688  static Color background = Color::MediumTurquoise();
689  static Color foreground = Color::Color::OrangeRed().WithAlpha(0.5);
690  static int current_blend_index = 3;
691 
692  if (AiksTest::ImGuiBegin("Controls", nullptr,
693  ImGuiWindowFlags_AlwaysAutoResize)) {
694  ImGui::ColorEdit4("Background", reinterpret_cast<float*>(&background));
695  ImGui::ColorEdit4("Foreground", reinterpret_cast<float*>(&foreground));
696  ImGui::ListBox("Blend mode", &current_blend_index,
697  modes.blend_mode_names.data(),
698  modes.blend_mode_names.size());
699  ImGui::End();
700  }
701 
702  DisplayListBuilder builder;
703  builder.Scale(0.2, 0.2);
704  DlPaint paint;
705  paint.setColor(DlColor(background.ToARGB()));
706  builder.DrawPaint(paint);
707 
708  paint.setColor(DlColor(foreground.ToARGB()));
709  paint.setBlendMode(static_cast<DlBlendMode>(current_blend_index));
710  builder.DrawPaint(paint);
711  return builder.Build();
712  };
713  ASSERT_TRUE(OpenPlaygroundHere(callback));
714 }
static BlendModeSelection GetBlendModeSelection()

References GetBlendModeSelection(), impeller::AiksPlayground::ImGuiBegin(), impeller::Color::MediumTurquoise(), impeller::Color::ToARGB(), and impeller::Color::WithAlpha().

◆ TEST_P() [21/497]

impeller::testing::TEST_P ( AiksTest  ,
CanDrawPaintWithAdvancedBlend   
)

Definition at line 108 of file aiks_dl_blend_unittests.cc.

108  {
109  DisplayListBuilder builder;
110 
111  builder.Scale(0.2, 0.2);
112  DlPaint paint;
113  paint.setColor(DlColor::RGBA(
114  Color::MediumTurquoise().red, Color::MediumTurquoise().green,
115  Color::MediumTurquoise().blue, Color::MediumTurquoise().alpha));
116  builder.DrawPaint(paint);
117 
118  paint.setColor(DlColor::RGBA(Color::OrangeRed().red, Color::OrangeRed().green,
119  Color::OrangeRed().blue, 0.5));
120  paint.setBlendMode(DlBlendMode::kHue);
121  builder.DrawPaint(paint);
122 
123  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
124 }

References impeller::Color::MediumTurquoise(), and impeller::Color::OrangeRed().

◆ TEST_P() [22/497]

impeller::testing::TEST_P ( AiksTest  ,
CanDrawPerspectiveTransformWithClips   
)

Definition at line 838 of file aiks_dl_basic_unittests.cc.

838  {
839  // Avoiding `GetSecondsElapsed()` to reduce risk of golden flakiness.
840  int time = 0;
841  auto callback = [&]() -> sk_sp<DisplayList> {
842  DisplayListBuilder builder;
843 
844  builder.Save();
845  {
846  builder.Translate(300, 300);
847 
848  // 1. Draw/restore a clip before drawing the image, which will get drawn
849  // to the depth buffer behind the image.
850  builder.Save();
851  {
852  DlPaint paint;
853  paint.setColor(DlColor::kGreen());
854  builder.DrawPaint(paint);
855  builder.ClipRect(SkRect::MakeLTRB(-180, -180, 180, 180),
856  DlCanvas::ClipOp::kDifference);
857 
858  paint.setColor(DlColor::kBlack());
859  builder.DrawPaint(paint);
860  }
861  builder.Restore(); // Restore rectangle difference clip.
862 
863  builder.Save();
864  {
865  // 2. Draw an oval clip that applies to the image, which will get drawn
866  // in front of the image on the depth buffer.
867  builder.ClipOval(SkRect::MakeLTRB(-200, -200, 200, 200));
868 
869  Matrix result =
870  Matrix(1.0, 0.0, 0.0, 0.0, //
871  0.0, 1.0, 0.0, 0.0, //
872  0.0, 0.0, 1.0, 0.003, //
873  0.0, 0.0, 0.0, 1.0) *
874  Matrix::MakeRotationY({Radians{-1.0f + (time++ / 60.0f)}});
875 
876  // 3. Draw the rotating image with a perspective transform.
877  builder.Transform(FromImpellerMatrix(result));
878 
879  auto image =
880  DlImageImpeller::Make(CreateTextureForFixture("airplane.jpg"));
881  auto position = -SkPoint::Make(image->dimensions().fWidth,
882  image->dimensions().fHeight) *
883  0.5;
884  builder.DrawImage(image, position, {});
885  }
886  builder.Restore(); // Restore oval intersect clip.
887 
888  // 4. Draw a semi-translucent blue circle atop all previous draws.
889  DlPaint paint;
890  paint.setColor(DlColor::kBlue().modulateOpacity(0.4));
891  builder.DrawCircle(SkPoint{}, 230, paint);
892  }
893  builder.Restore(); // Restore translation.
894 
895  return builder.Build();
896  };
897  ASSERT_TRUE(OpenPlaygroundHere(callback));
898 }

References impeller::DlImageImpeller::Make(), impeller::Matrix::MakeRotationY(), and impeller::Matrix::Transform().

◆ TEST_P() [23/497]

impeller::testing::TEST_P ( AiksTest  ,
CanDrawPoints   
)

Definition at line 413 of file aiks_dl_unittests.cc.

413  {
414  std::vector<SkPoint> points = {
415  {0, 0}, //
416  {100, 100}, //
417  {100, 0}, //
418  {0, 100}, //
419  {0, 0}, //
420  {48, 48}, //
421  {52, 52}, //
422  };
423  DlPaint paint_round;
424  paint_round.setColor(DlColor::kYellow().withAlpha(128));
425  paint_round.setStrokeCap(DlStrokeCap::kRound);
426  paint_round.setStrokeWidth(20);
427 
428  DlPaint paint_square;
429  paint_square.setColor(DlColor::kYellow().withAlpha(128));
430  paint_square.setStrokeCap(DlStrokeCap::kSquare);
431  paint_square.setStrokeWidth(20);
432 
433  DlPaint background;
434  background.setColor(DlColor::kBlack());
435 
436  DisplayListBuilder builder(GetCullRect(GetWindowSize()));
437  builder.DrawPaint(background);
438  builder.Translate(200, 200);
439 
440  builder.DrawPoints(DlCanvas::PointMode::kPoints, points.size(), points.data(),
441  paint_round);
442  builder.Translate(150, 0);
443  builder.DrawPoints(DlCanvas::PointMode::kPoints, points.size(), points.data(),
444  paint_square);
445 
446  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
447 }

◆ TEST_P() [24/497]

impeller::testing::TEST_P ( AiksTest  ,
CanDrawPointsWithTextureMap   
)

Definition at line 449 of file aiks_dl_unittests.cc.

449  {
450  auto texture = DlImageImpeller::Make(
451  CreateTextureForFixture("table_mountain_nx.png",
452  /*enable_mipmapping=*/true));
453 
454  std::vector<SkPoint> points = {
455  {0, 0}, //
456  {100, 100}, //
457  {100, 0}, //
458  {0, 100}, //
459  {0, 0}, //
460  {48, 48}, //
461  {52, 52}, //
462  };
463 
464  auto image_src =
465  DlColorSource::MakeImage(texture, DlTileMode::kClamp, DlTileMode::kClamp);
466 
467  DlPaint paint_round;
468  paint_round.setStrokeCap(DlStrokeCap::kRound);
469  paint_round.setColorSource(image_src);
470  paint_round.setStrokeWidth(200);
471 
472  DlPaint paint_square;
473  paint_square.setStrokeCap(DlStrokeCap::kSquare);
474  paint_square.setColorSource(image_src);
475  paint_square.setStrokeWidth(200);
476 
477  DisplayListBuilder builder(GetCullRect(GetWindowSize()));
478  builder.Translate(200, 200);
479 
480  builder.DrawPoints(DlCanvas::PointMode::kPoints, points.size(), points.data(),
481  paint_round);
482  builder.Translate(150, 0);
483  builder.DrawPoints(DlCanvas::PointMode::kPoints, points.size(), points.data(),
484  paint_square);
485 
486  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
487 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [25/497]

impeller::testing::TEST_P ( AiksTest  ,
CanDrawScaledPointsLargeScaleSmallRadius   
)

Definition at line 849 of file aiks_dl_unittests.cc.

849  {
850  std::vector<SkPoint> point = {
851  {0, 0}, //
852  };
853 
854  DlPaint paint;
855  paint.setStrokeCap(DlStrokeCap::kRound);
856  paint.setColor(DlColor::kRed());
857  paint.setStrokeWidth(100 * 0.000001);
858 
859  DisplayListBuilder builder(GetCullRect(GetWindowSize()));
860  builder.Translate(200, 200);
861  builder.Scale(1000000, 1000000);
862 
863  builder.DrawPoints(DlCanvas::PointMode::kPoints, point.size(), point.data(),
864  paint);
865  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
866 }

◆ TEST_P() [26/497]

impeller::testing::TEST_P ( AiksTest  ,
CanDrawScaledPointsSmallScaleLargeRadius   
)

Definition at line 828 of file aiks_dl_unittests.cc.

828  {
829  std::vector<SkPoint> point = {
830  {0, 0}, //
831  };
832 
833  DlPaint paint;
834  paint.setStrokeCap(DlStrokeCap::kRound);
835  paint.setColor(DlColor::kRed());
836  paint.setStrokeWidth(100 * 1000000);
837 
838  DisplayListBuilder builder(GetCullRect(GetWindowSize()));
839  builder.Translate(200, 200);
840  builder.Scale(0.000001, 0.000001);
841 
842  builder.DrawPoints(DlCanvas::PointMode::kPoints, point.size(), point.data(),
843  paint);
844 
845  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
846 }

◆ TEST_P() [27/497]

impeller::testing::TEST_P ( AiksTest  ,
CanEmptyPictureConvertToImage   
)

Definition at line 972 of file aiks_dl_unittests.cc.

972  {
973  DisplayListBuilder recorder_builder;
974 
975  DisplayListBuilder builder;
976  AiksContext renderer(GetContext(), nullptr);
977 
978  DlPaint paint;
979  paint.setColor(DlColor::kTransparent());
980  builder.DrawPaint(paint);
981 
982  auto result_image =
983  DisplayListToTexture(builder.Build(), ISize{1000, 1000}, renderer);
984  if (result_image) {
985  recorder_builder.DrawImage(DlImageImpeller::Make(result_image), SkPoint{},
986  {});
987 
988  paint.setColor(DlColor::RGBA(0.1, 0.1, 0.1, 0.2));
989  recorder_builder.DrawRect(SkRect::MakeSize({1000, 1000}), paint);
990  }
991 
992  ASSERT_TRUE(OpenPlaygroundHere(recorder_builder.Build()));
993 }

References impeller::DisplayListToTexture(), and impeller::DlImageImpeller::Make().

◆ TEST_P() [28/497]

impeller::testing::TEST_P ( AiksTest  ,
CanPerformFullScreenMSAA   
)

Definition at line 1162 of file aiks_dl_basic_unittests.cc.

1162  {
1163  DisplayListBuilder builder;
1164 
1165  DlPaint paint;
1166  paint.setColor(DlColor::kRed());
1167  builder.DrawCircle(SkPoint::Make(250, 250), 125, paint);
1168 
1169  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1170 }

◆ TEST_P() [29/497]

impeller::testing::TEST_P ( AiksTest  ,
CanPerformSaveLayerWithBounds   
)

Definition at line 1183 of file aiks_dl_basic_unittests.cc.

1183  {
1184  DisplayListBuilder builder;
1185 
1186  DlPaint save;
1187  save.setColor(DlColor::kBlack());
1188 
1189  SkRect save_bounds = SkRect::MakeXYWH(0, 0, 50, 50);
1190  builder.SaveLayer(&save_bounds, &save);
1191 
1192  DlPaint paint;
1193  paint.setColor(DlColor::kRed());
1194  builder.DrawRect(SkRect::MakeXYWH(0, 0, 100, 100), paint);
1195  paint.setColor(DlColor::kGreen());
1196  builder.DrawRect(SkRect::MakeXYWH(10, 10, 100, 100), paint);
1197  paint.setColor(DlColor::kBlue());
1198  builder.DrawRect(SkRect::MakeXYWH(20, 20, 100, 100), paint);
1199 
1200  builder.Restore();
1201 
1202  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1203 }

◆ TEST_P() [30/497]

impeller::testing::TEST_P ( AiksTest  ,
CanPerformSaveLayerWithBoundsAndLargerIntermediateIsNotAllocated   
)

Definition at line 1084 of file aiks_dl_basic_unittests.cc.

1085  {
1086  DisplayListBuilder builder;
1087 
1088  DlPaint red;
1089  red.setColor(DlColor::kRed());
1090 
1091  DlPaint green;
1092  green.setColor(DlColor::kGreen());
1093 
1094  DlPaint blue;
1095  blue.setColor(DlColor::kBlue());
1096 
1097  DlPaint save;
1098  save.setColor(DlColor::kBlack().modulateOpacity(0.5));
1099 
1100  SkRect huge_bounds = SkRect::MakeXYWH(0, 0, 100000, 100000);
1101  builder.SaveLayer(&huge_bounds, &save);
1102 
1103  builder.DrawRect(SkRect::MakeXYWH(0, 0, 100, 100), red);
1104  builder.DrawRect(SkRect::MakeXYWH(10, 10, 100, 100), green);
1105  builder.DrawRect(SkRect::MakeXYWH(20, 20, 100, 100), blue);
1106 
1107  builder.Restore();
1108 
1109  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1110 }

◆ TEST_P() [31/497]

impeller::testing::TEST_P ( AiksTest  ,
CanPerformSkew   
)

Definition at line 1172 of file aiks_dl_basic_unittests.cc.

1172  {
1173  DisplayListBuilder builder;
1174 
1175  DlPaint red;
1176  red.setColor(DlColor::kRed());
1177  builder.Skew(2, 5);
1178  builder.DrawRect(SkRect::MakeXYWH(0, 0, 100, 100), red);
1179 
1180  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1181 }

◆ TEST_P() [32/497]

impeller::testing::TEST_P ( AiksTest  ,
CanPictureConvertToImage   
)

Definition at line 945 of file aiks_dl_unittests.cc.

945  {
946  DisplayListBuilder recorder_canvas;
947  DlPaint paint;
948  paint.setColor(DlColor::RGBA(0.9568, 0.2627, 0.2118, 1.0));
949  recorder_canvas.DrawRect(SkRect::MakeXYWH(100.0, 100.0, 600, 600), paint);
950  paint.setColor(DlColor::RGBA(0.1294, 0.5882, 0.9529, 1.0));
951  recorder_canvas.DrawRect(SkRect::MakeXYWH(200.0, 200.0, 600, 600), paint);
952 
953  DisplayListBuilder canvas;
954  AiksContext renderer(GetContext(), nullptr);
955  paint.setColor(DlColor::kTransparent());
956  canvas.DrawPaint(paint);
957 
958  auto image =
959  DisplayListToTexture(recorder_canvas.Build(), {1000, 1000}, renderer);
960  if (image) {
961  canvas.DrawImage(DlImageImpeller::Make(image), SkPoint{}, {});
962  paint.setColor(DlColor::RGBA(0.1, 0.1, 0.1, 0.2));
963  canvas.DrawRect(SkRect::MakeSize({1000, 1000}), paint);
964  }
965 
966  ASSERT_TRUE(OpenPlaygroundHere(canvas.Build()));
967 }

References impeller::DisplayListToTexture(), and impeller::DlImageImpeller::Make().

◆ TEST_P() [33/497]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderAdvancedBlendColorFilterWithSaveLayer   
)

Definition at line 62 of file aiks_dl_blend_unittests.cc.

62  {
63  DisplayListBuilder builder;
64 
65  SkRect layer_rect = SkRect::MakeXYWH(0, 0, 500, 500);
66  builder.ClipRect(layer_rect);
67 
68  DlPaint save_paint;
69  save_paint.setColorFilter(DlColorFilter::MakeBlend(
70  DlColor::RGBA(0, 1, 0, 0.5), DlBlendMode::kDifference));
71  builder.SaveLayer(&layer_rect, &save_paint);
72 
73  DlPaint paint;
74  paint.setColor(DlColor::kBlack());
75  builder.DrawPaint(paint);
76  paint.setColor(DlColor::kWhite());
77  builder.DrawRect(SkRect::MakeXYWH(100, 100, 300, 300), paint);
78  builder.Restore();
79 
80  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
81 }

◆ TEST_P() [34/497]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderBackdropBlur   
)

Definition at line 242 of file aiks_dl_blur_unittests.cc.

242  {
243  DisplayListBuilder builder;
244 
245  DlPaint paint;
246  paint.setColor(DlColor::kCornflowerBlue());
247  builder.DrawCircle(SkPoint{100, 100}, 50, paint);
248 
249  paint.setColor(DlColor::kGreenYellow());
250  builder.DrawCircle(SkPoint{300, 200}, 100, paint);
251 
252  paint.setColor(DlColor::kDarkMagenta());
253  builder.DrawCircle(SkPoint{140, 170}, 75, paint);
254 
255  paint.setColor(DlColor::kOrangeRed());
256  builder.DrawCircle(SkPoint{180, 120}, 100, paint);
257 
258  SkRRect rrect =
259  SkRRect::MakeRectXY(SkRect::MakeLTRB(75, 50, 375, 275), 20, 20);
260  builder.ClipRRect(rrect);
261 
262  DlPaint save_paint;
263  save_paint.setBlendMode(DlBlendMode::kSrc);
264  auto backdrop_filter = DlImageFilter::MakeBlur(30, 30, DlTileMode::kClamp);
265  builder.SaveLayer(nullptr, &save_paint, backdrop_filter.get());
266  builder.Restore();
267 
268  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
269 }

◆ TEST_P() [35/497]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderBackdropBlurHugeSigma   
)

Definition at line 352 of file aiks_dl_blur_unittests.cc.

352  {
353  DisplayListBuilder builder;
354 
355  DlPaint paint;
356  paint.setColor(DlColor::kGreen());
357  builder.DrawCircle(SkPoint{400, 400}, 300, paint);
358 
359  DlPaint save_paint;
360  save_paint.setBlendMode(DlBlendMode::kSrc);
361 
362  auto backdrop_filter =
363  DlImageFilter::MakeBlur(999999, 999999, DlTileMode::kClamp);
364  builder.SaveLayer(nullptr, &save_paint, backdrop_filter.get());
365  builder.Restore();
366 
367  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
368 }

◆ TEST_P() [36/497]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderBackdropBlurInteractive   
)

Definition at line 205 of file aiks_dl_blur_unittests.cc.

205  {
206  auto callback = [&]() -> sk_sp<DisplayList> {
207  static PlaygroundPoint point_a(Point(50, 50), 30, Color::White());
208  static PlaygroundPoint point_b(Point(300, 200), 30, Color::White());
209  auto [a, b] = DrawPlaygroundLine(point_a, point_b);
210 
211  DisplayListBuilder builder;
212  DlPaint paint;
213  paint.setColor(DlColor::kCornflowerBlue());
214  builder.DrawCircle(SkPoint{100, 100}, 50, paint);
215 
216  paint.setColor(DlColor::kGreenYellow());
217  builder.DrawCircle(SkPoint{300, 200}, 100, paint);
218 
219  paint.setColor(DlColor::kDarkMagenta());
220  builder.DrawCircle(SkPoint{140, 170}, 75, paint);
221 
222  paint.setColor(DlColor::kOrangeRed());
223  builder.DrawCircle(SkPoint{180, 120}, 100, paint);
224 
225  SkRRect rrect =
226  SkRRect::MakeRectXY(SkRect::MakeLTRB(a.x, a.y, b.x, b.y), 20, 20);
227  builder.ClipRRect(rrect);
228 
229  DlPaint save_paint;
230  save_paint.setBlendMode(DlBlendMode::kSrc);
231 
232  auto backdrop_filter = DlImageFilter::MakeBlur(20, 20, DlTileMode::kClamp);
233  builder.SaveLayer(nullptr, &save_paint, backdrop_filter.get());
234  builder.Restore();
235 
236  return builder.Build();
237  };
238 
239  ASSERT_TRUE(OpenPlaygroundHere(callback));
240 }
std::tuple< Point, Point > DrawPlaygroundLine(PlaygroundPoint &point_a, PlaygroundPoint &point_b)
Definition: widgets.cc:50

References impeller::saturated::b, impeller::DrawPlaygroundLine(), and impeller::Color::White().

◆ TEST_P() [37/497]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderBackdropBlurWithSingleBackdropId   
)

Definition at line 271 of file aiks_dl_blur_unittests.cc.

271  {
272  auto image = DlImageImpeller::Make(CreateTextureForFixture("kalimba.jpg"));
273 
274  DisplayListBuilder builder;
275 
276  DlPaint paint;
277  builder.DrawImage(image, SkPoint::Make(50.0, 50.0),
278  DlImageSampling::kNearestNeighbor, &paint);
279 
280  SkRRect rrect =
281  SkRRect::MakeRectXY(SkRect::MakeXYWH(50, 250, 100, 100), 20, 20);
282  builder.Save();
283  builder.ClipRRect(rrect);
284 
285  DlPaint save_paint;
286  save_paint.setBlendMode(DlBlendMode::kSrc);
287  auto backdrop_filter = DlImageFilter::MakeBlur(30, 30, DlTileMode::kClamp);
288  builder.SaveLayer(nullptr, &save_paint, backdrop_filter.get(),
289  /*backdrop_id=*/1);
290  builder.Restore();
291  builder.Restore();
292 
293  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
294 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [38/497]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderClippedBackdropFilter   
)

Definition at line 799 of file aiks_dl_basic_unittests.cc.

799  {
800  DisplayListBuilder builder;
801 
802  builder.Scale(GetContentScale().x, GetContentScale().y);
803 
804  // Draw something interesting in the background.
805  std::vector<DlColor> colors = {DlColor::RGBA(0.9568, 0.2627, 0.2118, 1.0),
806  DlColor::RGBA(0.1294, 0.5882, 0.9529, 1.0)};
807  std::vector<Scalar> stops = {
808  0.0,
809  1.0,
810  };
811  DlPaint paint;
812  paint.setColorSource(DlColorSource::MakeLinear(
813  /*start_point=*/{0, 0}, //
814  /*end_point=*/{100, 100}, //
815  /*stop_count=*/2, //
816  /*colors=*/colors.data(), //
817  /*stops=*/stops.data(), //
818  /*tile_mode=*/DlTileMode::kRepeat //
819  ));
820 
821  builder.DrawPaint(paint);
822 
823  SkRect clip_rect = SkRect::MakeLTRB(50, 50, 400, 300);
824  SkRRect clip_rrect = SkRRect::MakeRectXY(clip_rect, 100, 100);
825 
826  // Draw a clipped SaveLayer, where the clip coverage and SaveLayer size are
827  // the same.
828  builder.ClipRRect(clip_rrect, DlCanvas::ClipOp::kIntersect);
829 
830  DlPaint save_paint;
831  auto backdrop_filter = DlImageFilter::MakeColorFilter(
832  DlColorFilter::MakeBlend(DlColor::kRed(), DlBlendMode::kExclusion));
833  builder.SaveLayer(&clip_rect, &save_paint, backdrop_filter.get());
834 
835  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
836 }

References x.

◆ TEST_P() [39/497]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderClippedBlur   
)

Definition at line 370 of file aiks_dl_blur_unittests.cc.

370  {
371  DisplayListBuilder builder;
372  builder.ClipRect(SkRect::MakeXYWH(100, 150, 400, 400));
373 
374  DlPaint paint;
375  paint.setColor(DlColor::kGreen());
376  paint.setImageFilter(DlImageFilter::MakeBlur(20, 20, DlTileMode::kDecal));
377  builder.DrawCircle(SkPoint{400, 400}, 200, paint);
378  builder.Restore();
379 
380  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
381 }

◆ TEST_P() [40/497]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderClippedLayers   
)

Definition at line 1419 of file aiks_dl_basic_unittests.cc.

1419  {
1420  DisplayListBuilder builder;
1421 
1422  DlPaint paint;
1423  paint.setColor(DlColor::kWhite());
1424  builder.DrawPaint(paint);
1425 
1426  // Draw a green circle on the screen.
1427  {
1428  // Increase the clip depth for the savelayer to contend with.
1429  SkPath path = SkPath::Circle(100, 100, 50);
1430  builder.ClipPath(path);
1431 
1432  SkRect bounds = SkRect::MakeXYWH(50, 50, 100, 100);
1433  DlPaint save_paint;
1434  builder.SaveLayer(&bounds, &save_paint);
1435 
1436  // Fill the layer with white.
1437  paint.setColor(DlColor::kWhite());
1438  builder.DrawRect(SkRect::MakeSize(SkSize{400, 400}), paint);
1439  // Fill the layer with green, but do so with a color blend that can't be
1440  // collapsed into the parent pass.
1441  paint.setColor(DlColor::kGreen());
1442  paint.setBlendMode(DlBlendMode::kHardLight);
1443  builder.DrawRect(SkRect::MakeSize(SkSize{400, 400}), paint);
1444  }
1445 
1446  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1447 }

◆ TEST_P() [41/497]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderClippedRuntimeEffects   
)

Definition at line 42 of file aiks_dl_runtime_effect_unittests.cc.

42  {
43  struct FragUniforms {
44  Vector2 iResolution;
45  Scalar iTime;
46  } frag_uniforms = {.iResolution = Vector2(400, 400), .iTime = 100.0};
47  auto uniform_data = std::make_shared<std::vector<uint8_t>>();
48  uniform_data->resize(sizeof(FragUniforms));
49  memcpy(uniform_data->data(), &frag_uniforms, sizeof(FragUniforms));
50 
51  DlPaint paint;
52  paint.setColorSource(
53  MakeRuntimeEffect(this, "runtime_stage_example.frag.iplr", uniform_data));
54 
55  DisplayListBuilder builder;
56  builder.Save();
57  builder.ClipRRect(
58  SkRRect::MakeRectXY(SkRect::MakeXYWH(0, 0, 400, 400), 10.0, 10.0),
59  DlCanvas::ClipOp::kIntersect);
60  builder.DrawRect(SkRect::MakeXYWH(0, 0, 400, 400), paint);
61  builder.Restore();
62 
63  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
64 }

◆ TEST_P() [42/497]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderClips   
)

Definition at line 453 of file aiks_dl_path_unittests.cc.

453  {
454  DisplayListBuilder builder;
455  DlPaint paint;
456  paint.setColor(DlColor::kFuchsia());
457 
458  builder.ClipPath(SkPath::Rect(SkRect::MakeXYWH(0, 0, 500, 500)));
459  builder.DrawPath(SkPath::Circle(500, 500, 250), paint);
460 
461  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
462 }

◆ TEST_P() [43/497]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderColoredRect   
)

Definition at line 36 of file aiks_dl_basic_unittests.cc.

36  {
37  DisplayListBuilder builder;
38  DlPaint paint;
39  paint.setColor(DlColor::kBlue());
40  SkPath path = SkPath();
41  path.addRect(SkRect::MakeXYWH(100.0, 100.0, 100.0, 100.0));
42  builder.DrawPath(path, paint);
43  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
44 }

◆ TEST_P() [44/497]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderColorFilterWithInvertColors   
)

Definition at line 70 of file aiks_dl_basic_unittests.cc.

70  {
71  DisplayListBuilder builder;
72  DlPaint paint;
73  paint.setColor(DlColor::kRed());
74  paint.setColorFilter(
75  DlColorFilter::MakeBlend(DlColor::kYellow(), DlBlendMode::kSrcOver));
76  paint.setInvertColors(true);
77 
78  builder.DrawRect(SkRect::MakeLTRB(0, 0, 100, 100), paint);
79  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
80 }

◆ TEST_P() [45/497]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderColorFilterWithInvertColorsDrawPaint   
)

Definition at line 82 of file aiks_dl_basic_unittests.cc.

82  {
83  DisplayListBuilder builder;
84  DlPaint paint;
85  paint.setColor(DlColor::kRed());
86  paint.setColorFilter(
87  DlColorFilter::MakeBlend(DlColor::kYellow(), DlBlendMode::kSrcOver));
88  paint.setInvertColors(true);
89 
90  builder.DrawPaint(paint);
91  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
92 }

◆ TEST_P() [46/497]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderConicalGradient   
)

Definition at line 667 of file aiks_dl_gradient_unittests.cc.

667  {
668  Scalar size = 256;
669  DisplayListBuilder builder;
670  DlPaint paint;
671  paint.setColor(DlColor::kWhite());
672  builder.DrawRect(SkRect::MakeXYWH(0, 0, size * 3, size * 3), paint);
673  std::vector<DlColor> colors = {
674  DlColor(Color::MakeRGBA8(0xF4, 0x43, 0x36, 0xFF).ToARGB()),
675  DlColor(Color::MakeRGBA8(0xFF, 0xEB, 0x3B, 0xFF).ToARGB()),
676  DlColor(Color::MakeRGBA8(0x4c, 0xAF, 0x50, 0xFF).ToARGB()),
677  DlColor(Color::MakeRGBA8(0x21, 0x96, 0xF3, 0xFF).ToARGB())};
678  std::vector<Scalar> stops = {0.0, 1.f / 3.f, 2.f / 3.f, 1.0};
679  std::array<std::tuple<DlPoint, float, DlPoint, float>, 8> array{
680  std::make_tuple(DlPoint(size / 2.f, size / 2.f), 0.f,
681  DlPoint(size / 2.f, size / 2.f), size / 2.f),
682  std::make_tuple(DlPoint(size / 2.f, size / 2.f), size / 4.f,
683  DlPoint(size / 2.f, size / 2.f), size / 2.f),
684  std::make_tuple(DlPoint(size / 4.f, size / 4.f), 0.f,
685  DlPoint(size / 2.f, size / 2.f), size / 2.f),
686  std::make_tuple(DlPoint(size / 4.f, size / 4.f), size / 2.f,
687  DlPoint(size / 2.f, size / 2.f), 0),
688  std::make_tuple(DlPoint(size / 4.f, size / 4.f), size / 4.f,
689  DlPoint(size / 2.f, size / 2.f), size / 2.f),
690  std::make_tuple(DlPoint(size / 4.f, size / 4.f), size / 16.f,
691  DlPoint(size / 2.f, size / 2.f), size / 8.f),
692  std::make_tuple(DlPoint(size / 4.f, size / 4.f), size / 8.f,
693  DlPoint(size / 2.f, size / 2.f), size / 16.f),
694  std::make_tuple(DlPoint(size / 8.f, size / 8.f), size / 8.f,
695  DlPoint(size / 2.f, size / 2.f), size / 8.f),
696  };
697  for (int i = 0; i < 8; i++) {
698  builder.Save();
699  builder.Translate((i % 3) * size, i / 3 * size);
700  paint.setColorSource(DlColorSource::MakeConical(
701  std::get<2>(array[i]), std::get<3>(array[i]), std::get<0>(array[i]),
702  std::get<1>(array[i]), stops.size(), colors.data(), stops.data(),
703  DlTileMode::kClamp));
704  builder.DrawRect(SkRect::MakeXYWH(0, 0, size, size), paint);
705  builder.Restore();
706  }
707  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
708 }

◆ TEST_P() [47/497]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderConicalGradientWithDitheringEnabled   
)

Definition at line 186 of file aiks_dl_gradient_unittests.cc.

186  {
188 }
static void CanRenderConicalGradientWithDithering(AiksTest *aiks_test)

References CanRenderConicalGradientWithDithering().

◆ TEST_P() [48/497]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderConicalGradientWithIncompleteStops   
)

Definition at line 328 of file aiks_dl_gradient_unittests.cc.

328  {
329  CanRenderGradientWithIncompleteStops(this,
330  DlColorSourceType::kConicalGradient);
331 }

◆ TEST_P() [49/497]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderCurvedStrokes   
)

Definition at line 69 of file aiks_dl_path_unittests.cc.

69  {
70  DisplayListBuilder builder;
71  DlPaint paint;
72  paint.setColor(DlColor::kRed());
73  paint.setStrokeWidth(25);
74  paint.setDrawStyle(DlDrawStyle::kStroke);
75 
76  builder.DrawPath(SkPath::Circle(500, 500, 250), paint);
77 
78  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
79 }

◆ TEST_P() [50/497]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderDestructiveSaveLayer   
)

Definition at line 391 of file aiks_dl_unittests.cc.

391  {
392  DisplayListBuilder builder(GetCullRect(GetWindowSize()));
393 
394  DlPaint paint;
395  paint.setColor(DlColor::kRed());
396  builder.DrawPaint(paint);
397  // Draw an empty savelayer with a destructive blend mode, which will replace
398  // the entire red screen with fully transparent black, except for the green
399  // circle drawn within the layer.
400 
401  DlPaint save_paint;
402  save_paint.setBlendMode(DlBlendMode::kSrc);
403  builder.SaveLayer(nullptr, &save_paint);
404 
405  DlPaint draw_paint;
406  draw_paint.setColor(DlColor::kGreen());
407  builder.DrawCircle(SkPoint{300, 300}, 100, draw_paint);
408  builder.Restore();
409 
410  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
411 }

◆ TEST_P() [51/497]

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 }

◆ TEST_P() [52/497]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderDifferencePaths   
)

Definition at line 156 of file aiks_dl_path_unittests.cc.

156  {
157  DisplayListBuilder builder;
158 
159  DlPaint paint;
160  paint.setColor(DlColor::kRed());
161 
162  SkPoint radii[4] = {{50, 25}, {25, 50}, {50, 25}, {25, 50}};
163  SkPath path;
164  SkRRect rrect;
165  rrect.setRectRadii(SkRect::MakeXYWH(100, 100, 200, 200), radii);
166  path.addRRect(rrect);
167  path.addCircle(200, 200, 50);
168  path.setFillType(SkPathFillType::kEvenOdd);
169 
170  builder.DrawImage(
171  DlImageImpeller::Make(CreateTextureForFixture("boston.jpg")),
172  SkPoint{10, 10}, {});
173  builder.DrawPath(path, paint);
174 
175  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
176 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [53/497]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderDifferentShapesWithSameColorSource   
)

Definition at line 357 of file aiks_dl_basic_unittests.cc.

357  {
358  DisplayListBuilder builder;
359  DlPaint paint;
360 
361  DlColor colors[2] = {
362  DlColor::RGBA(0.9568, 0.2627, 0.2118, 1.0),
363  DlColor::RGBA(0.1294, 0.5882, 0.9529, 1.0),
364  };
365  DlScalar stops[2] = {
366  0.0,
367  1.0,
368  };
369 
370  paint.setColorSource(DlColorSource::MakeLinear(
371  /*start_point=*/{0, 0}, //
372  /*end_point=*/{100, 100}, //
373  /*stop_count=*/2, //
374  /*colors=*/colors, //
375  /*stops=*/stops, //
376  /*tile_mode=*/DlTileMode::kRepeat //
377  ));
378 
379  builder.Save();
380  builder.Translate(100, 100);
381  builder.DrawRect(SkRect::MakeXYWH(0, 0, 200, 200), paint);
382  builder.Restore();
383 
384  builder.Save();
385  builder.Translate(100, 400);
386  builder.DrawCircle(SkPoint{100, 100}, 100, paint);
387  builder.Restore();
388  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
389 }
flutter::DlScalar DlScalar
Definition: dl_dispatcher.h:23

◆ TEST_P() [54/497]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderEmojiTextFrame   
)

Definition at line 295 of file aiks_dl_text_unittests.cc.

295  {
296  DisplayListBuilder builder;
297 
298  DlPaint paint;
299  paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
300  builder.DrawPaint(paint);
301 
302  ASSERT_TRUE(RenderTextInCanvasSkia(
303  GetContext(), builder, "😀 😃 😄 😁 😆 😅 😂 🤣 🥲 😊", kFontFixture));
304  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
305 }
bool RenderTextInCanvasSkia(const std::shared_ptr< Context > &context, DisplayListBuilder &canvas, const std::string &text, const std::string_view &font_fixture, const TextRenderOptions &options={})
static constexpr std::string_view kFontFixture

References kFontFixture, and RenderTextInCanvasSkia().

◆ TEST_P() [55/497]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderEmojiTextFrameWithAlpha   
)

Definition at line 323 of file aiks_dl_text_unittests.cc.

323  {
324  DisplayListBuilder builder;
325 
326  DlPaint paint;
327  paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
328  builder.DrawPaint(paint);
329 
330  ASSERT_TRUE(RenderTextInCanvasSkia(
331  GetContext(), builder, "😀 😃 😄 😁 😆 😅 😂 🤣 🥲 😊", kFontFixture,
332  {.color = DlColor::kBlack().modulateOpacity(0.5)}));
333  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
334 }

References kFontFixture, and RenderTextInCanvasSkia().

◆ TEST_P() [56/497]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderEmojiTextFrameWithBlur   
)

Definition at line 307 of file aiks_dl_text_unittests.cc.

307  {
308  DisplayListBuilder builder;
309 
310  builder.Scale(GetContentScale().x, GetContentScale().y);
311  DlPaint paint;
312  paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
313  builder.DrawPaint(paint);
314 
315  ASSERT_TRUE(RenderTextInCanvasSkia(
316  GetContext(), builder, "😀 😃 😄 😁 😆 😅 😂 🤣 🥲 😊", kFontFixture,
317  TextRenderOptions{
318  .color = DlColor::kBlue(),
319  .filter = DlBlurMaskFilter::Make(DlBlurStyle::kNormal, 4)}));
320  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
321 }

References impeller::testing::TextRenderOptions::color, kFontFixture, RenderTextInCanvasSkia(), and x.

◆ TEST_P() [57/497]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderForegroundAdvancedBlendWithMaskBlur   
)

Definition at line 184 of file aiks_dl_blur_unittests.cc.

184  {
185  // This case triggers the ForegroundAdvancedBlend path. The color filter
186  // should apply to the color only, and respect the alpha mask.
187  DisplayListBuilder builder;
188  builder.ClipRect(SkRect::MakeXYWH(100, 150, 400, 400));
189 
190  DlPaint paint;
191  paint.setColor(
192  DlColor::RGBA(128.0f / 255.0f, 128.0f / 255.0f, 128.0f / 255.0f, 1.0f));
193 
194  Sigma sigma = Radius(20);
195  paint.setMaskFilter(
196  DlBlurMaskFilter::Make(DlBlurStyle::kNormal, sigma.sigma));
197  paint.setColorFilter(
198  DlColorFilter::MakeBlend(DlColor::kGreen(), DlBlendMode::kColor));
199  builder.DrawCircle(SkPoint{400, 400}, 200, paint);
200  builder.Restore();
201 
202  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
203 }

References impeller::Sigma::sigma.

◆ TEST_P() [58/497]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderForegroundBlendWithMaskBlur   
)

Definition at line 165 of file aiks_dl_blur_unittests.cc.

165  {
166  // This case triggers the ForegroundPorterDuffBlend path. The color filter
167  // should apply to the color only, and respect the alpha mask.
168  DisplayListBuilder builder;
169  builder.ClipRect(SkRect::MakeXYWH(100, 150, 400, 400));
170 
171  DlPaint paint;
172  paint.setColor(DlColor::kWhite());
173 
174  Sigma sigma = Radius(20);
175  paint.setMaskFilter(
176  DlBlurMaskFilter::Make(DlBlurStyle::kNormal, sigma.sigma));
177  paint.setColorFilter(
178  DlColorFilter::MakeBlend(DlColor::kGreen(), DlBlendMode::kSrc));
179  builder.DrawCircle(SkPoint{400, 400}, 200, paint);
180 
181  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
182 }

References impeller::Sigma::sigma.

◆ TEST_P() [59/497]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderGradientDecalWithBackground   
)

Definition at line 710 of file aiks_dl_gradient_unittests.cc.

710  {
711  std::vector<DlColor> colors = {
712  DlColor(Color::MakeRGBA8(0xF4, 0x43, 0x36, 0xFF).ToARGB()),
713  DlColor(Color::MakeRGBA8(0xFF, 0xEB, 0x3B, 0xFF).ToARGB()),
714  DlColor(Color::MakeRGBA8(0x4c, 0xAF, 0x50, 0xFF).ToARGB()),
715  DlColor(Color::MakeRGBA8(0x21, 0x96, 0xF3, 0xFF).ToARGB())};
716  std::vector<Scalar> stops = {0.0, 1.f / 3.f, 2.f / 3.f, 1.0};
717 
718  std::array<std::shared_ptr<DlColorSource>, 3> color_sources = {
719  DlColorSource::MakeLinear({0, 0}, {100, 100}, stops.size(), colors.data(),
720  stops.data(), DlTileMode::kDecal),
721  DlColorSource::MakeRadial({100, 100}, 100, stops.size(), colors.data(),
722  stops.data(), DlTileMode::kDecal),
723  DlColorSource::MakeSweep({100, 100}, 45, 135, stops.size(), colors.data(),
724  stops.data(), DlTileMode::kDecal),
725  };
726 
727  DisplayListBuilder builder;
728  DlPaint paint;
729  paint.setColor(DlColor::kWhite());
730  builder.DrawRect(SkRect::MakeLTRB(0, 0, 605, 205), paint);
731  for (int i = 0; i < 3; i++) {
732  builder.Save();
733  builder.Translate(i * 200.0f, 0);
734  paint.setColorSource(color_sources[i]);
735  builder.DrawRect(SkRect::MakeLTRB(0, 0, 200, 200), paint);
736  builder.Restore();
737  }
738  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
739 }

◆ TEST_P() [60/497]

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() [61/497]

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() [62/497]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderImage   
)

Definition at line 46 of file aiks_dl_basic_unittests.cc.

46  {
47  DisplayListBuilder builder;
48  DlPaint paint;
49  paint.setColor(DlColor::kRed());
50  auto image = DlImageImpeller::Make(CreateTextureForFixture("kalimba.jpg"));
51  builder.DrawImage(image, SkPoint::Make(100.0, 100.0),
52  DlImageSampling::kNearestNeighbor, &paint);
53  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
54 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [63/497]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderImageRect   
)

Definition at line 217 of file aiks_dl_basic_unittests.cc.

217  {
218  DisplayListBuilder builder;
219  auto image = DlImageImpeller::Make(CreateTextureForFixture("kalimba.jpg"));
220 
221  SkSize image_half_size = SkSize::Make(image->dimensions().fWidth * 0.5f,
222  image->dimensions().fHeight * 0.5f);
223 
224  // Render the bottom right quarter of the source image in a stretched rect.
225  auto source_rect = SkRect::MakeSize(image_half_size);
226  source_rect =
227  source_rect.makeOffset(image_half_size.fWidth, image_half_size.fHeight);
228 
229  builder.DrawImageRect(image, source_rect,
230  SkRect::MakeXYWH(100, 100, 600, 600),
231  DlImageSampling::kNearestNeighbor);
232  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
233 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [64/497]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderInvertedImageWithColorFilter   
)

Definition at line 56 of file aiks_dl_basic_unittests.cc.

56  {
57  DisplayListBuilder builder;
58  DlPaint paint;
59  paint.setColor(DlColor::kRed());
60  paint.setColorFilter(
61  DlColorFilter::MakeBlend(DlColor::kYellow(), DlBlendMode::kSrcOver));
62  paint.setInvertColors(true);
63  auto image = DlImageImpeller::Make(CreateTextureForFixture("kalimba.jpg"));
64 
65  builder.DrawImage(image, SkPoint::Make(100.0, 100.0),
66  DlImageSampling::kNearestNeighbor, &paint);
67  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
68 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [65/497]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderItalicizedText   
)

Definition at line 275 of file aiks_dl_text_unittests.cc.

275  {
276  DisplayListBuilder builder;
277 
278  DlPaint paint;
279  paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
280  builder.DrawPaint(paint);
281 
282  ASSERT_TRUE(RenderTextInCanvasSkia(
283  GetContext(), builder, "the quick brown fox jumped over the lazy dog!.?",
284  "HomemadeApple.ttf"));
285  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
286 }

References RenderTextInCanvasSkia().

◆ TEST_P() [66/497]

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() [67/497]

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() [68/497]

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(DlColorFilter::MakeBlend(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 scale, and impeller::Color::ToARGB().

◆ TEST_P() [69/497]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderLinearGradientManyColorsClamp   
)

Definition at line 373 of file aiks_dl_gradient_unittests.cc.

373  {
374  CanRenderLinearGradientManyColors(this, DlTileMode::kClamp);
375 }

◆ TEST_P() [70/497]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderLinearGradientManyColorsDecal   
)

Definition at line 382 of file aiks_dl_gradient_unittests.cc.

382  {
383  CanRenderLinearGradientManyColors(this, DlTileMode::kDecal);
384 }

◆ TEST_P() [71/497]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderLinearGradientManyColorsMirror   
)

Definition at line 379 of file aiks_dl_gradient_unittests.cc.

379  {
380  CanRenderLinearGradientManyColors(this, DlTileMode::kMirror);
381 }

◆ TEST_P() [72/497]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderLinearGradientManyColorsRepeat   
)

Definition at line 376 of file aiks_dl_gradient_unittests.cc.

376  {
377  CanRenderLinearGradientManyColors(this, DlTileMode::kRepeat);
378 }

◆ TEST_P() [73/497]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderLinearGradientManyColorsUnevenStops   
)

Definition at line 417 of file aiks_dl_gradient_unittests.cc.

417  {
418  auto callback = [&]() -> sk_sp<DisplayList> {
419  const char* tile_mode_names[] = {"Clamp", "Repeat", "Mirror", "Decal"};
420  const DlTileMode tile_modes[] = {DlTileMode::kClamp, DlTileMode::kRepeat,
421  DlTileMode::kMirror, DlTileMode::kDecal};
422 
423  static int selected_tile_mode = 0;
424  static Matrix matrix;
425  if (AiksTest::ImGuiBegin("Controls", nullptr,
426  ImGuiWindowFlags_AlwaysAutoResize)) {
427  ImGui::Combo("Tile mode", &selected_tile_mode, tile_mode_names,
428  sizeof(tile_mode_names) / sizeof(char*));
429  std::string label = "##1";
430  for (int i = 0; i < 4; i++) {
431  ImGui::InputScalarN(label.c_str(), ImGuiDataType_Float,
432  &(matrix.vec[i]), 4, NULL, NULL, "%.2f", 0);
433  label[2]++;
434  }
435  ImGui::End();
436  }
437 
438  DisplayListBuilder builder;
439  DlPaint paint;
440  builder.Translate(100.0, 100.0);
441  auto tile_mode = tile_modes[selected_tile_mode];
442 
443  std::vector<DlColor> colors = {
444  DlColor(Color{0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0}.ToARGB()),
445  DlColor(Color{0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0}.ToARGB()),
446  DlColor(Color{0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0}.ToARGB()),
447  DlColor(Color{0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0}.ToARGB()),
448  DlColor(Color{0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0}.ToARGB()),
449  DlColor(Color{0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0}.ToARGB()),
450  DlColor(Color{0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0}.ToARGB())};
451  std::vector<Scalar> stops = {
452  0.0, 2.0 / 62.0, 4.0 / 62.0, 8.0 / 62.0, 16.0 / 62.0, 32.0 / 62.0, 1.0,
453  };
454 
455  paint.setColorSource(DlColorSource::MakeLinear({0, 0}, {200, 200},
456  stops.size(), colors.data(),
457  stops.data(), tile_mode));
458 
459  builder.DrawRect(SkRect::MakeXYWH(0, 0, 600, 600), paint);
460  return builder.Build();
461  };
462  ASSERT_TRUE(OpenPlaygroundHere(callback));
463 }

References impeller::Color::ToARGB(), and impeller::Matrix::vec.

◆ TEST_P() [74/497]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderLinearGradientMaskBlur   
)

Definition at line 465 of file aiks_dl_gradient_unittests.cc.

465  {
466  DisplayListBuilder builder;
467 
468  std::vector<DlColor> colors = {
469  DlColor::kRed(), DlColor::kWhite(), DlColor::kRed(), DlColor::kWhite(),
470  DlColor::kRed(), DlColor::kWhite(), DlColor::kRed(), DlColor::kWhite(),
471  DlColor::kRed(), DlColor::kWhite(), DlColor::kRed()};
472  std::vector<Scalar> stops = {0.0, 0.1, 0.2, 0.3, 0.4, 0.5,
473  0.6, 0.7, 0.8, 0.9, 1.0};
474 
475  DlPaint paint;
476  paint.setColor(DlColor::kWhite());
477  paint.setColorSource(DlColorSource::MakeLinear(
478  {200, 200}, {400, 400}, stops.size(), colors.data(), stops.data(),
479  DlTileMode::kClamp));
480  paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kNormal, 20));
481 
482  builder.DrawCircle(SkPoint{300, 300}, 200, paint);
483  builder.DrawRect(SkRect::MakeLTRB(100, 300, 500, 600), paint);
484 
485  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
486 }

◆ TEST_P() [75/497]

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() [76/497]

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() [77/497]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderLinearGradientWayManyColorsClamp   
)

Definition at line 413 of file aiks_dl_gradient_unittests.cc.

413  {
414  CanRenderLinearGradientWayManyColors(this, DlTileMode::kClamp);
415 }

◆ TEST_P() [78/497]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderLinearGradientWithDitheringEnabled   
)

Definition at line 120 of file aiks_dl_gradient_unittests.cc.

120  {
122 }
static void CanRenderLinearGradientWithDithering(AiksTest *aiks_test)

References CanRenderLinearGradientWithDithering().

◆ TEST_P() [79/497]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderLinearGradientWithIncompleteStops   
)

Definition at line 320 of file aiks_dl_gradient_unittests.cc.

320  {
321  CanRenderGradientWithIncompleteStops(this,
322  DlColorSourceType::kLinearGradient);
323 }

◆ TEST_P() [80/497]

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() [81/497]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderMaskBlurHugeSigma   
)

Definition at line 153 of file aiks_dl_blur_unittests.cc.

153  {
154  DisplayListBuilder builder;
155 
156  DlPaint paint;
157  paint.setColor(DlColor::kGreen());
158  paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kNormal, 99999));
159  builder.DrawCircle(SkPoint{400, 400}, 300, paint);
160  builder.Restore();
161 
162  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
163 }

◆ TEST_P() [82/497]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderMultipleBackdropBlurWithSingleBackdropId   
)

Definition at line 296 of file aiks_dl_blur_unittests.cc.

296  {
297  auto image = DlImageImpeller::Make(CreateTextureForFixture("kalimba.jpg"));
298 
299  DisplayListBuilder builder;
300 
301  DlPaint paint;
302  builder.DrawImage(image, SkPoint::Make(50.0, 50.0),
303  DlImageSampling::kNearestNeighbor, &paint);
304 
305  for (int i = 0; i < 6; i++) {
306  SkRRect rrect = SkRRect::MakeRectXY(
307  SkRect::MakeXYWH(50 + (i * 100), 250, 100, 100), 20, 20);
308  builder.Save();
309  builder.ClipRRect(rrect);
310 
311  DlPaint save_paint;
312  save_paint.setBlendMode(DlBlendMode::kSrc);
313  auto backdrop_filter = DlImageFilter::MakeBlur(30, 30, DlTileMode::kClamp);
314  builder.SaveLayer(nullptr, &save_paint, backdrop_filter.get(),
315  /*backdrop_id=*/1);
316  builder.Restore();
317  builder.Restore();
318  }
319 
320  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
321 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [83/497]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderMultipleBackdropBlurWithSingleBackdropIdAndDistinctFilters   
)

Definition at line 323 of file aiks_dl_blur_unittests.cc.

324  {
325  auto image = DlImageImpeller::Make(CreateTextureForFixture("kalimba.jpg"));
326 
327  DisplayListBuilder builder;
328 
329  DlPaint paint;
330  builder.DrawImage(image, SkPoint::Make(50.0, 50.0),
331  DlImageSampling::kNearestNeighbor, &paint);
332 
333  for (int i = 0; i < 6; i++) {
334  SkRRect rrect = SkRRect::MakeRectXY(
335  SkRect::MakeXYWH(50 + (i * 100), 250, 100, 100), 20, 20);
336  builder.Save();
337  builder.ClipRRect(rrect);
338 
339  DlPaint save_paint;
340  save_paint.setBlendMode(DlBlendMode::kSrc);
341  auto backdrop_filter =
342  DlImageFilter::MakeBlur(30 + i, 30, DlTileMode::kClamp);
343  builder.SaveLayer(nullptr, &save_paint, backdrop_filter.get(),
344  /*backdrop_id=*/1);
345  builder.Restore();
346  builder.Restore();
347  }
348 
349  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
350 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [84/497]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderMultipleBackdropBlurWithSingleBackdropIdDifferentLayers   
)

Definition at line 1365 of file aiks_dl_blur_unittests.cc.

1366  {
1367  auto image = DlImageImpeller::Make(CreateTextureForFixture("kalimba.jpg"));
1368 
1369  DisplayListBuilder builder;
1370 
1371  DlPaint paint;
1372  builder.DrawImage(image, SkPoint::Make(50.0, 50.0),
1373  DlImageSampling::kNearestNeighbor, &paint);
1374 
1375  for (int i = 0; i < 6; i++) {
1376  if (i != 0) {
1377  DlPaint paint;
1378  paint.setColor(DlColor::kWhite().withAlphaF(0.95));
1379  builder.SaveLayer(nullptr, &paint);
1380  }
1381  SkRRect rrect = SkRRect::MakeRectXY(
1382  SkRect::MakeXYWH(50 + (i * 100), 250, 100, 100), 20, 20);
1383  builder.Save();
1384  builder.ClipRRect(rrect);
1385 
1386  DlPaint save_paint;
1387  save_paint.setBlendMode(DlBlendMode::kSrc);
1388  auto backdrop_filter = DlImageFilter::MakeBlur(30, 30, DlTileMode::kClamp);
1389  builder.SaveLayer(nullptr, &save_paint, backdrop_filter.get(),
1390  /*backdrop_id=*/1);
1391  builder.Restore();
1392  builder.Restore();
1393  if (i != 0) {
1394  builder.Restore();
1395  }
1396  }
1397 
1398  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1399 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [85/497]

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 }

◆ TEST_P() [86/497]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderOverlappingMultiContourPath   
)

Definition at line 503 of file aiks_dl_path_unittests.cc.

503  {
504  DisplayListBuilder builder;
505 
506  DlPaint paint;
507  paint.setColor(DlColor::kRed());
508 
509  SkPoint radii[4] = {{50, 50}, {50, 50}, {50, 50}, {50, 50}};
510 
511  const Scalar kTriangleHeight = 100;
512  SkRRect rrect;
513  rrect.setRectRadii(
514  SkRect::MakeXYWH(-kTriangleHeight / 2.0f, -kTriangleHeight / 2.0f,
515  kTriangleHeight, kTriangleHeight),
516  radii //
517  );
518 
519  builder.Translate(200, 200);
520  // Form a path similar to the Material drop slider value indicator. Both
521  // shapes should render identically side-by-side.
522  {
523  SkPath path;
524  path.moveTo(0, kTriangleHeight);
525  path.lineTo(-kTriangleHeight / 2.0f, 0);
526  path.lineTo(kTriangleHeight / 2.0f, 0);
527  path.close();
528  path.addRRect(rrect);
529 
530  builder.DrawPath(path, paint);
531  }
532  builder.Translate(100, 0);
533 
534  {
535  SkPath path;
536  path.moveTo(0, kTriangleHeight);
537  path.lineTo(-kTriangleHeight / 2.0f, 0);
538  path.lineTo(0, -10);
539  path.lineTo(kTriangleHeight / 2.0f, 0);
540  path.close();
541  path.addRRect(rrect);
542 
543  builder.DrawPath(path, paint);
544  }
545 
546  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
547 }

◆ TEST_P() [87/497]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderQuadraticStrokeWithInstantTurn   
)

Definition at line 136 of file aiks_dl_path_unittests.cc.

136  {
137  DisplayListBuilder builder;
138 
139  DlPaint paint;
140  paint.setColor(DlColor::kRed());
141  paint.setStrokeWidth(50);
142  paint.setDrawStyle(DlDrawStyle::kStroke);
143  paint.setStrokeCap(DlStrokeCap::kRound);
144 
145  // Should draw a diagonal pill shape. If flat on either end, the stroke is
146  // rendering wrong.
147  SkPath path;
148  path.moveTo(250, 250);
149  path.quadTo(100, 100, 250, 250);
150 
151  builder.DrawPath(path, paint);
152 
153  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
154 }

◆ TEST_P() [88/497]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderRadialGradient   
)

Definition at line 488 of file aiks_dl_gradient_unittests.cc.

488  {
489  auto callback = [&]() -> sk_sp<DisplayList> {
490  const char* tile_mode_names[] = {"Clamp", "Repeat", "Mirror", "Decal"};
491  const DlTileMode tile_modes[] = {DlTileMode::kClamp, DlTileMode::kRepeat,
492  DlTileMode::kMirror, DlTileMode::kDecal};
493 
494  static int selected_tile_mode = 0;
495  static Matrix matrix;
496  if (AiksTest::ImGuiBegin("Controls", nullptr,
497  ImGuiWindowFlags_AlwaysAutoResize)) {
498  ImGui::Combo("Tile mode", &selected_tile_mode, tile_mode_names,
499  sizeof(tile_mode_names) / sizeof(char*));
500  std::string label = "##1";
501  for (int i = 0; i < 4; i++) {
502  ImGui::InputScalarN(label.c_str(), ImGuiDataType_Float,
503  &(matrix.vec[i]), 4, NULL, NULL, "%.2f", 0);
504  label[2]++;
505  }
506  ImGui::End();
507  }
508 
509  DisplayListBuilder builder;
510  DlPaint paint;
511  builder.Translate(100.0, 100.0);
512  auto tile_mode = tile_modes[selected_tile_mode];
513 
514  std::vector<DlColor> colors = {
515  DlColor(Color{0.9568, 0.2627, 0.2118, 1.0}.ToARGB()),
516  DlColor(Color{0.1294, 0.5882, 0.9529, 1.0}.ToARGB())};
517  std::vector<Scalar> stops = {0.0, 1.0};
518 
519  paint.setColorSource(DlColorSource::MakeRadial(
520  {100, 100}, 100, 2, colors.data(), stops.data(), tile_mode));
521 
522  builder.DrawRect(SkRect::MakeXYWH(0, 0, 600, 600), paint);
523  return builder.Build();
524  };
525  ASSERT_TRUE(OpenPlaygroundHere(callback));
526 }

References impeller::Color::ToARGB(), and impeller::Matrix::vec.

◆ TEST_P() [89/497]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderRadialGradientManyColors   
)

Definition at line 528 of file aiks_dl_gradient_unittests.cc.

528  {
529  auto callback = [&]() -> sk_sp<DisplayList> {
530  const char* tile_mode_names[] = {"Clamp", "Repeat", "Mirror", "Decal"};
531  const DlTileMode tile_modes[] = {DlTileMode::kClamp, DlTileMode::kRepeat,
532  DlTileMode::kMirror, DlTileMode::kDecal};
533 
534  static int selected_tile_mode = 0;
535  static Matrix matrix = {
536  1, 0, 0, 0, //
537  0, 1, 0, 0, //
538  0, 0, 1, 0, //
539  0, 0, 0, 1 //
540  };
541  if (AiksTest::ImGuiBegin("Controls", nullptr,
542  ImGuiWindowFlags_AlwaysAutoResize)) {
543  ImGui::Combo("Tile mode", &selected_tile_mode, tile_mode_names,
544  sizeof(tile_mode_names) / sizeof(char*));
545  std::string label = "##1";
546  for (int i = 0; i < 4; i++) {
547  ImGui::InputScalarN(label.c_str(), ImGuiDataType_Float,
548  &(matrix.vec[i]), 4, NULL, NULL, "%.2f", 0);
549  label[2]++;
550  }
551  ImGui::End();
552  }
553 
554  DisplayListBuilder builder;
555  DlPaint paint;
556  builder.Translate(100.0, 100.0);
557  auto tile_mode = tile_modes[selected_tile_mode];
558 
559  std::vector<DlColor> colors = {
560  DlColor(Color{0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0}.ToARGB()),
561  DlColor(Color{0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0}.ToARGB()),
562  DlColor(Color{0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0}.ToARGB()),
563  DlColor(Color{0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0}.ToARGB()),
564  DlColor(Color{0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0}.ToARGB()),
565  DlColor(Color{0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0}.ToARGB()),
566  DlColor(Color{0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0}.ToARGB())};
567  std::vector<Scalar> stops = {
568  0.0,
569  (1.0 / 6.0) * 1,
570  (1.0 / 6.0) * 2,
571  (1.0 / 6.0) * 3,
572  (1.0 / 6.0) * 4,
573  (1.0 / 6.0) * 5,
574  1.0,
575  };
576 
577  paint.setColorSource(DlColorSource::MakeRadial(
578  {100, 100}, 100, stops.size(), colors.data(), stops.data(), tile_mode));
579 
580  builder.DrawRect(SkRect::MakeXYWH(0, 0, 600, 600), paint);
581  return builder.Build();
582  };
583  ASSERT_TRUE(OpenPlaygroundHere(callback));
584 }

References impeller::Color::ToARGB(), and impeller::Matrix::vec.

◆ TEST_P() [90/497]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderRadialGradientWithDitheringEnabled   
)

Definition at line 140 of file aiks_dl_gradient_unittests.cc.

140  {
142 }
static void CanRenderRadialGradientWithDithering(AiksTest *aiks_test)

References CanRenderRadialGradientWithDithering().

◆ TEST_P() [91/497]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderRadialGradientWithIncompleteStops   
)

Definition at line 324 of file aiks_dl_gradient_unittests.cc.

324  {
325  CanRenderGradientWithIncompleteStops(this,
326  DlColorSourceType::kRadialGradient);
327 }

◆ TEST_P() [92/497]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderRoundedRectWithNonUniformRadii   
)

Definition at line 391 of file aiks_dl_basic_unittests.cc.

391  {
392  DisplayListBuilder builder;
393  DlPaint paint;
394  paint.setColor(DlColor::kRed());
395 
396  SkRRect rrect;
397  SkVector radii[4] = {
398  SkVector{50, 25},
399  SkVector{25, 50},
400  SkVector{50, 25},
401  SkVector{25, 50},
402  };
403  rrect.setRectRadii(SkRect::MakeXYWH(100, 100, 500, 500), radii);
404 
405  builder.DrawRRect(rrect, paint);
406 
407  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
408 }

◆ TEST_P() [93/497]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderRuntimeEffectFilter   
)

Definition at line 87 of file aiks_dl_runtime_effect_unittests.cc.

87  {
88  auto runtime_stages =
89  OpenAssetAsRuntimeStage("runtime_stage_filter_example.frag.iplr");
90 
91  std::shared_ptr<RuntimeStage> runtime_stage =
92  runtime_stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
93  ASSERT_TRUE(runtime_stage);
94  ASSERT_TRUE(runtime_stage->IsDirty());
95 
96  std::vector<std::shared_ptr<DlColorSource>> sampler_inputs = {
97  nullptr,
98  };
99  auto uniform_data = std::make_shared<std::vector<uint8_t>>();
100  uniform_data->resize(sizeof(Vector2));
101 
102  DlPaint paint;
103  paint.setColor(DlColor::kAqua());
104  paint.setImageFilter(DlImageFilter::MakeRuntimeEffect(
105  DlRuntimeEffect::MakeImpeller(runtime_stage), sampler_inputs,
106  uniform_data));
107 
108  DisplayListBuilder builder;
109  builder.DrawRect(SkRect::MakeXYWH(0, 0, 400, 400), paint);
110 
111  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
112 }
constexpr RuntimeStageBackend PlaygroundBackendToRuntimeStageBackend(PlaygroundBackend backend)
Definition: playground.h:33

References impeller::PlaygroundBackendToRuntimeStageBackend().

◆ TEST_P() [94/497]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderSimpleClips   
)

Definition at line 255 of file aiks_dl_basic_unittests.cc.

255  {
256  DisplayListBuilder builder;
257  builder.Scale(GetContentScale().x, GetContentScale().y);
258  DlPaint paint;
259 
260  paint.setColor(DlColor::kWhite());
261  builder.DrawPaint(paint);
262 
263  auto draw = [&builder](const DlPaint& paint, Scalar x, Scalar y) {
264  builder.Save();
265  builder.Translate(x, y);
266  {
267  builder.Save();
268  builder.ClipRect(SkRect::MakeLTRB(50, 50, 150, 150));
269  builder.DrawPaint(paint);
270  builder.Restore();
271  }
272  {
273  builder.Save();
274  builder.ClipOval(SkRect::MakeLTRB(200, 50, 300, 150));
275  builder.DrawPaint(paint);
276  builder.Restore();
277  }
278  {
279  builder.Save();
280  builder.ClipRRect(
281  SkRRect::MakeRectXY(SkRect::MakeLTRB(50, 200, 150, 300), 20, 20));
282  builder.DrawPaint(paint);
283  builder.Restore();
284  }
285  {
286  builder.Save();
287  builder.ClipRRect(
288  SkRRect::MakeRectXY(SkRect::MakeLTRB(200, 230, 300, 270), 20, 20));
289  builder.DrawPaint(paint);
290  builder.Restore();
291  }
292  {
293  builder.Save();
294  builder.ClipRRect(
295  SkRRect::MakeRectXY(SkRect::MakeLTRB(230, 200, 270, 300), 20, 20));
296  builder.DrawPaint(paint);
297  builder.Restore();
298  }
299  builder.Restore();
300  };
301 
302  paint.setColor(DlColor::kBlue());
303  draw(paint, 0, 0);
304 
305  DlColor gradient_colors[7] = {
306  DlColor::RGBA(0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0),
307  DlColor::RGBA(0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0),
308  DlColor::RGBA(0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0),
309  DlColor::RGBA(0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0),
310  DlColor::RGBA(0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0),
311  DlColor::RGBA(0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0),
312  DlColor::RGBA(0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0),
313  };
314  Scalar stops[7] = {
315  0.0,
316  (1.0 / 6.0) * 1,
317  (1.0 / 6.0) * 2,
318  (1.0 / 6.0) * 3,
319  (1.0 / 6.0) * 4,
320  (1.0 / 6.0) * 5,
321  1.0,
322  };
323  auto texture = CreateTextureForFixture("airplane.jpg",
324  /*enable_mipmapping=*/true);
325  auto image = DlImageImpeller::Make(texture);
326 
327  paint.setColorSource(DlColorSource::MakeRadial(
328  {500, 600}, 75, 7, gradient_colors, stops, DlTileMode::kMirror));
329  draw(paint, 0, 300);
330 
331  paint.setColorSource(
332  DlColorSource::MakeImage(image, DlTileMode::kRepeat, DlTileMode::kRepeat,
333  DlImageSampling::kNearestNeighbor));
334  draw(paint, 300, 0);
335 
336  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
337 }

References impeller::DlImageImpeller::Make(), and x.

◆ TEST_P() [95/497]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderStrokedTextFrame   
)

Definition at line 117 of file aiks_dl_text_unittests.cc.

117  {
118  DisplayListBuilder builder;
119 
120  DlPaint paint;
121  paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
122  builder.DrawPaint(paint);
123 
124  ASSERT_TRUE(RenderTextInCanvasSkia(
125  GetContext(), builder, "the quick brown fox jumped over the lazy dog!.?",
126  "Roboto-Regular.ttf",
127  {
128  .stroke = true,
129  }));
130  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
131 }

References RenderTextInCanvasSkia().

◆ TEST_P() [96/497]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderStrokePathThatEndsAtSharpTurn   
)

Definition at line 105 of file aiks_dl_path_unittests.cc.

105  {
106  DisplayListBuilder builder;
107  DlPaint paint;
108  paint.setColor(DlColor::kRed());
109  paint.setStrokeWidth(200);
110  paint.setDrawStyle(DlDrawStyle::kStroke);
111 
112  SkPath path;
113  path.arcTo(SkRect::MakeXYWH(100, 100, 200, 200), 0, 90, false);
114 
115  builder.DrawPath(path, paint);
116 
117  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
118 }

◆ TEST_P() [97/497]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderStrokePathWithCubicLine   
)

Definition at line 120 of file aiks_dl_path_unittests.cc.

120  {
121  DisplayListBuilder builder;
122 
123  DlPaint paint;
124  paint.setColor(DlColor::kRed());
125  paint.setStrokeWidth(20);
126  paint.setDrawStyle(DlDrawStyle::kStroke);
127 
128  SkPath path;
129  path.moveTo(0, 200);
130  path.cubicTo(50, 400, 350, 0, 400, 200);
131 
132  builder.DrawPath(path, paint);
133  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
134 }

◆ TEST_P() [98/497]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderStrokes   
)

Definition at line 57 of file aiks_dl_path_unittests.cc.

57  {
58  DisplayListBuilder builder;
59  DlPaint paint;
60  paint.setColor(DlColor::kRed());
61  paint.setStrokeWidth(20);
62  paint.setDrawStyle(DlDrawStyle::kStroke);
63 
64  builder.DrawPath(SkPath::Line({200, 100}, {800, 100}), paint);
65 
66  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
67 }

◆ TEST_P() [99/497]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderSweepGradientClamp   
)

Definition at line 607 of file aiks_dl_gradient_unittests.cc.

607  {
608  CanRenderSweepGradient(this, DlTileMode::kClamp);
609 }

◆ TEST_P() [100/497]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderSweepGradientDecal   
)

Definition at line 616 of file aiks_dl_gradient_unittests.cc.

616  {
617  CanRenderSweepGradient(this, DlTileMode::kDecal);
618 }

◆ TEST_P() [101/497]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderSweepGradientManyColorsClamp   
)

Definition at line 654 of file aiks_dl_gradient_unittests.cc.

654  {
655  CanRenderSweepGradientManyColors(this, DlTileMode::kClamp);
656 }

◆ TEST_P() [102/497]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderSweepGradientManyColorsDecal   
)

Definition at line 663 of file aiks_dl_gradient_unittests.cc.

663  {
664  CanRenderSweepGradientManyColors(this, DlTileMode::kDecal);
665 }

◆ TEST_P() [103/497]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderSweepGradientManyColorsMirror   
)

Definition at line 660 of file aiks_dl_gradient_unittests.cc.

660  {
661  CanRenderSweepGradientManyColors(this, DlTileMode::kMirror);
662 }

◆ TEST_P() [104/497]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderSweepGradientManyColorsRepeat   
)

Definition at line 657 of file aiks_dl_gradient_unittests.cc.

657  {
658  CanRenderSweepGradientManyColors(this, DlTileMode::kRepeat);
659 }

◆ TEST_P() [105/497]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderSweepGradientMirror   
)

Definition at line 613 of file aiks_dl_gradient_unittests.cc.

613  {
614  CanRenderSweepGradient(this, DlTileMode::kMirror);
615 }

◆ TEST_P() [106/497]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderSweepGradientRepeat   
)

Definition at line 610 of file aiks_dl_gradient_unittests.cc.

610  {
611  CanRenderSweepGradient(this, DlTileMode::kRepeat);
612 }

◆ TEST_P() [107/497]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderSweepGradientWithDitheringEnabled   
)

Definition at line 163 of file aiks_dl_gradient_unittests.cc.

163  {
165 }
static void CanRenderSweepGradientWithDithering(AiksTest *aiks_test)

References CanRenderSweepGradientWithDithering().

◆ TEST_P() [108/497]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderSweepGradientWithIncompleteStops   
)

Definition at line 332 of file aiks_dl_gradient_unittests.cc.

332  {
333  CanRenderGradientWithIncompleteStops(this, DlColorSourceType::kSweepGradient);
334 }

◆ TEST_P() [109/497]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderTextFrame   
)

Definition at line 88 of file aiks_dl_text_unittests.cc.

88  {
89  DisplayListBuilder builder;
90 
91  DlPaint paint;
92  paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
93  builder.DrawPaint(paint);
94  ASSERT_TRUE(RenderTextInCanvasSkia(
95  GetContext(), builder, "the quick brown fox jumped over the lazy dog!.?",
96  "Roboto-Regular.ttf"));
97 
98  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
99 }

References RenderTextInCanvasSkia().

◆ TEST_P() [110/497]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderTextFrameWithFractionScaling   
)

Definition at line 163 of file aiks_dl_text_unittests.cc.

163  {
164  Scalar fine_scale = 0.f;
165  bool is_subpixel = false;
166  auto callback = [&]() -> sk_sp<DisplayList> {
167  if (AiksTest::ImGuiBegin("Controls", nullptr,
168  ImGuiWindowFlags_AlwaysAutoResize)) {
169  ImGui::SliderFloat("Fine Scale", &fine_scale, -1, 1);
170  ImGui::Checkbox("subpixel", &is_subpixel);
171  ImGui::End();
172  }
173 
174  DisplayListBuilder builder;
175  DlPaint paint;
176  paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
177  builder.DrawPaint(paint);
178  Scalar scale = 2.625 + fine_scale;
179  builder.Scale(scale, scale);
180  RenderTextInCanvasSkia(GetContext(), builder,
181  "the quick brown fox jumped over the lazy dog!.?",
182  "Roboto-Regular.ttf",
183  TextRenderOptions{.is_subpixel = is_subpixel});
184  return builder.Build();
185  };
186 
187  ASSERT_TRUE(OpenPlaygroundHere(callback));
188 }

References impeller::testing::TextRenderOptions::is_subpixel, RenderTextInCanvasSkia(), and scale.

◆ TEST_P() [111/497]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderTextFrameWithHalfScaling   
)

Definition at line 149 of file aiks_dl_text_unittests.cc.

149  {
150  DisplayListBuilder builder;
151 
152  DlPaint paint;
153  paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
154  builder.DrawPaint(paint);
155  builder.Scale(0.5, 0.5);
156 
157  ASSERT_TRUE(RenderTextInCanvasSkia(
158  GetContext(), builder, "the quick brown fox jumped over the lazy dog!.?",
159  "Roboto-Regular.ttf"));
160  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
161 }

References RenderTextInCanvasSkia().

◆ TEST_P() [112/497]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderTextFrameWithInvertedTransform   
)

Definition at line 101 of file aiks_dl_text_unittests.cc.

101  {
102  DisplayListBuilder builder;
103 
104  DlPaint paint;
105  paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
106  builder.DrawPaint(paint);
107  builder.Translate(1000, 0);
108  builder.Scale(-1, 1);
109 
110  ASSERT_TRUE(RenderTextInCanvasSkia(
111  GetContext(), builder, "the quick brown fox jumped over the lazy dog!.?",
112  "Roboto-Regular.ttf"));
113 
114  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
115 }

References RenderTextInCanvasSkia().

◆ TEST_P() [113/497]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderTextInSaveLayer   
)

Definition at line 336 of file aiks_dl_text_unittests.cc.

336  {
337  DisplayListBuilder builder;
338 
339  DlPaint paint;
340  paint.setColor(DlColor::ARGB(0.1, 0.1, 0.1, 0.1));
341  builder.DrawPaint(paint);
342 
343  builder.Translate(100, 100);
344  builder.Scale(0.5, 0.5);
345 
346  // Blend the layer with the parent pass using kClear to expose the coverage.
347  paint.setBlendMode(DlBlendMode::kClear);
348  builder.SaveLayer(nullptr, &paint);
349  ASSERT_TRUE(RenderTextInCanvasSkia(
350  GetContext(), builder, "the quick brown fox jumped over the lazy dog!.?",
351  "Roboto-Regular.ttf"));
352  builder.Restore();
353 
354  // Render the text again over the cleared coverage rect.
355  ASSERT_TRUE(RenderTextInCanvasSkia(
356  GetContext(), builder, "the quick brown fox jumped over the lazy dog!.?",
357  "Roboto-Regular.ttf"));
358 
359  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
360 }

References RenderTextInCanvasSkia().

◆ TEST_P() [114/497]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderTextOutsideBoundaries   
)

Definition at line 362 of file aiks_dl_text_unittests.cc.

362  {
363  DisplayListBuilder builder;
364  builder.Translate(200, 150);
365 
366  // Construct the text blob.
367  auto mapping = flutter::testing::OpenFixtureAsSkData("wtf.otf");
368  ASSERT_NE(mapping, nullptr);
369 
370  Scalar font_size = 80;
371  sk_sp<SkFontMgr> font_mgr = txt::GetDefaultFontManager();
372  SkFont sk_font(font_mgr->makeFromData(mapping), font_size);
373 
374  DlPaint text_paint;
375  text_paint.setColor(DlColor::kBlue().withAlpha(255 * 0.8));
376 
377  struct {
378  SkPoint position;
379  const char* text;
380  } text[] = {{SkPoint::Make(0, 0), "0F0F0F0"},
381  {SkPoint::Make(1, 2), "789"},
382  {SkPoint::Make(1, 3), "456"},
383  {SkPoint::Make(1, 4), "123"},
384  {SkPoint::Make(0, 6), "0F0F0F0"}};
385  for (auto& t : text) {
386  builder.Save();
387  builder.Translate(t.position.x() * font_size * 2,
388  t.position.y() * font_size * 1.1);
389  {
390  auto blob = SkTextBlob::MakeFromString(t.text, sk_font);
391  ASSERT_NE(blob, nullptr);
392  auto frame = MakeTextFrameFromTextBlobSkia(blob);
393  builder.DrawTextFrame(frame, 0, 0, text_paint);
394  }
395  builder.Restore();
396  }
397 
398  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
399 }

References impeller::MakeTextFrameFromTextBlobSkia().

◆ TEST_P() [115/497]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderTextStrokeWidth   
)

Definition at line 133 of file aiks_dl_text_unittests.cc.

133  {
134  DisplayListBuilder builder;
135 
136  DlPaint paint;
137  paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
138  builder.DrawPaint(paint);
139 
140  ASSERT_TRUE(RenderTextInCanvasSkia(GetContext(), builder, "LMNOP VWXYZ",
141  "Roboto-Medium.ttf",
142  {
143  .stroke = true,
144  .stroke_width = 4,
145  }));
146  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
147 }

References RenderTextInCanvasSkia().

◆ TEST_P() [116/497]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderTextWithLargePerspectiveTransform   
)

Definition at line 460 of file aiks_dl_text_unittests.cc.

460  {
461  // Verifies that text scales are clamped to work around
462  // https://github.com/flutter/flutter/issues/136112 .
463 
464  DisplayListBuilder builder;
465 
466  DlPaint save_paint;
467  builder.SaveLayer(nullptr, &save_paint);
468  builder.Transform(SkM44::ColMajor(Matrix(2000, 0, 0, 0, //
469  0, 2000, 0, 0, //
470  0, 0, -1, 9000, //
471  0, 0, -1, 7000 //
472  )
473  .m));
474 
475  ASSERT_TRUE(RenderTextInCanvasSkia(GetContext(), builder, "Hello world",
476  "Roboto-Regular.ttf"));
477  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
478 }

References RenderTextInCanvasSkia().

◆ TEST_P() [117/497]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderTextWithPerspectiveTransformInSublist   
)

Definition at line 480 of file aiks_dl_text_unittests.cc.

480  {
481  DisplayListBuilder text_builder;
482  ASSERT_TRUE(RenderTextInCanvasSkia(GetContext(), text_builder, "Hello world",
483  "Roboto-Regular.ttf"));
484  auto text_display_list = text_builder.Build();
485 
486  DisplayListBuilder builder;
487 
488  Matrix matrix = Matrix::MakeRow(2.0, 0.0, 0.0, 0.0, //
489  0.0, 2.0, 0.0, 0.0, //
490  0.0, 0.0, 1.0, 0.0, //
491  0.0, 0.002, 0.0, 1.0);
492 
493  DlPaint save_paint;
494  SkRect window_bounds =
495  SkRect::MakeXYWH(0, 0, GetWindowSize().width, GetWindowSize().height);
496  builder.SaveLayer(&window_bounds, &save_paint);
497  builder.Transform(SkM44::ColMajor(matrix.m));
498  builder.DrawDisplayList(text_display_list, 1.0f);
499  builder.Restore();
500 
501  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
502 }

References impeller::Matrix::m, and RenderTextInCanvasSkia().

◆ TEST_P() [118/497]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderThickCurvedStrokes   
)

Definition at line 81 of file aiks_dl_path_unittests.cc.

81  {
82  DisplayListBuilder builder;
83  DlPaint paint;
84  paint.setColor(DlColor::kRed());
85  paint.setStrokeWidth(100);
86  paint.setDrawStyle(DlDrawStyle::kStroke);
87 
88  builder.DrawPath(SkPath::Circle(100, 100, 50), paint);
89 
90  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
91 }

◆ TEST_P() [119/497]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderThinCurvedStrokes   
)

Definition at line 93 of file aiks_dl_path_unittests.cc.

93  {
94  DisplayListBuilder builder;
95  DlPaint paint;
96  paint.setColor(DlColor::kRed());
97  paint.setStrokeWidth(0.01);
98  paint.setDrawStyle(DlDrawStyle::kStroke);
99 
100  builder.DrawPath(SkPath::Circle(100, 100, 50), paint);
101 
102  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
103 }

◆ TEST_P() [120/497]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderTiledTextureClamp   
)

Definition at line 196 of file aiks_dl_basic_unittests.cc.

196  {
197  CanRenderTiledTexture(this, DlTileMode::kClamp);
198 }

◆ TEST_P() [121/497]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderTiledTextureClampWithTranslate   
)

Definition at line 212 of file aiks_dl_basic_unittests.cc.

212  {
213  CanRenderTiledTexture(this, DlTileMode::kClamp,
214  Matrix::MakeTranslation({172.f, 172.f, 0.f}));
215 }

References impeller::Matrix::MakeTranslation().

◆ TEST_P() [122/497]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderTiledTextureDecal   
)

Definition at line 208 of file aiks_dl_basic_unittests.cc.

208  {
209  CanRenderTiledTexture(this, DlTileMode::kDecal);
210 }

◆ TEST_P() [123/497]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderTiledTextureMirror   
)

Definition at line 204 of file aiks_dl_basic_unittests.cc.

204  {
205  CanRenderTiledTexture(this, DlTileMode::kMirror);
206 }

◆ TEST_P() [124/497]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderTiledTextureRepeat   
)

Definition at line 200 of file aiks_dl_basic_unittests.cc.

200  {
201  CanRenderTiledTexture(this, DlTileMode::kRepeat);
202 }

◆ TEST_P() [125/497]

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 366 of file aiks_dl_unittests.cc.

366  {
367  DisplayListBuilder builder(GetCullRect(GetWindowSize()));
368 
369  DlPaint paint;
370  paint.setColor(DlColor::kRed());
371  builder.DrawPaint(paint);
372 
373  // Draw two overlapping subpixel circles.
374  builder.SaveLayer({});
375 
376  DlPaint yellow_paint;
377  yellow_paint.setColor(DlColor::kYellow());
378  builder.DrawCircle(SkPoint{100, 100}, 0.1, yellow_paint);
379  builder.Restore();
380  builder.SaveLayer({});
381  builder.DrawCircle(SkPoint{100, 100}, 0.1, yellow_paint);
382  builder.Restore();
383 
384  DlPaint draw_paint;
385  draw_paint.setColor(DlColor::kGreen());
386  builder.DrawPaint(draw_paint);
387 
388  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
389 }

◆ TEST_P() [126/497]

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 }

◆ TEST_P() [127/497]

impeller::testing::TEST_P ( AiksTest  ,
CanSaveLayerStandalone   
)

Definition at line 339 of file aiks_dl_basic_unittests.cc.

339  {
340  DisplayListBuilder builder;
341 
342  DlPaint red;
343  red.setColor(DlColor::kRed());
344 
345  DlPaint alpha;
346  alpha.setColor(DlColor::kRed().modulateOpacity(0.5));
347 
348  builder.SaveLayer(nullptr, &alpha);
349 
350  builder.DrawCircle(SkPoint{125, 125}, 125, red);
351 
352  builder.Restore();
353 
354  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
355 }

◆ TEST_P() [128/497]

impeller::testing::TEST_P ( AiksTest  ,
CanvasCanPushPopCTM   
)

Definition at line 110 of file canvas_unittests.cc.

110  {
111  ContentContext context(GetContext(), nullptr);
112  auto canvas = CreateTestCanvas(context);
113 
114  ASSERT_EQ(canvas->GetSaveCount(), 1u);
115  ASSERT_EQ(canvas->Restore(), false);
116 
117  canvas->Translate(Size{100, 100});
118  canvas->Save(10);
119  ASSERT_EQ(canvas->GetSaveCount(), 2u);
120  ASSERT_MATRIX_NEAR(canvas->GetCurrentTransform(),
121  Matrix::MakeTranslation({100.0, 100.0, 0.0}));
122  ASSERT_TRUE(canvas->Restore());
123  ASSERT_EQ(canvas->GetSaveCount(), 1u);
124  ASSERT_MATRIX_NEAR(canvas->GetCurrentTransform(),
125  Matrix::MakeTranslation({100.0, 100.0, 0.0}));
126 }

References ASSERT_MATRIX_NEAR, CreateTestCanvas(), and impeller::Matrix::MakeTranslation().

◆ TEST_P() [129/497]

impeller::testing::TEST_P ( AiksTest  ,
CanvasCTMCanBeUpdated   
)

Definition at line 128 of file canvas_unittests.cc.

128  {
129  ContentContext context(GetContext(), nullptr);
130  auto canvas = CreateTestCanvas(context);
131 
132  Matrix identity;
133  ASSERT_MATRIX_NEAR(canvas->GetCurrentTransform(), identity);
134  canvas->Translate(Size{100, 100});
135  ASSERT_MATRIX_NEAR(canvas->GetCurrentTransform(),
136  Matrix::MakeTranslation({100.0, 100.0, 0.0}));
137 }

References ASSERT_MATRIX_NEAR, CreateTestCanvas(), and impeller::Matrix::MakeTranslation().

◆ TEST_P() [130/497]

impeller::testing::TEST_P ( AiksTest  ,
ClearBlend   
)

Definition at line 487 of file aiks_dl_blend_unittests.cc.

487  {
488  DisplayListBuilder builder;
489 
490  DlPaint blue;
491  blue.setColor(DlColor::kBlue());
492  builder.DrawRect(SkRect::MakeXYWH(0, 0, 600.0, 600.0), blue);
493 
494  DlPaint clear;
495  clear.setBlendMode(DlBlendMode::kClear);
496 
497  builder.DrawCircle(SkPoint{300.0, 300.0}, 200.0, clear);
498 
499  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
500 }

◆ TEST_P() [131/497]

impeller::testing::TEST_P ( AiksTest  ,
ClearBlendWithBlur   
)

Definition at line 424 of file aiks_dl_blur_unittests.cc.

424  {
425  DisplayListBuilder builder;
426  DlPaint paint;
427  paint.setColor(DlColor::kBlue());
428  builder.DrawRect(SkRect::MakeXYWH(0, 0, 600.0, 600.0), paint);
429 
430  DlPaint clear;
431  clear.setBlendMode(DlBlendMode::kClear);
432  clear.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kNormal, 20));
433 
434  builder.DrawCircle(SkPoint{300.0, 300.0}, 200.0, clear);
435 
436  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
437 }

◆ TEST_P() [132/497]

impeller::testing::TEST_P ( AiksTest  ,
ClearColorOptimizationWhenSubpassIsBiggerThanParentPass   
)

Definition at line 1028 of file aiks_dl_basic_unittests.cc.

1028  {
1029  SetWindowSize({400, 400});
1030  DisplayListBuilder builder;
1031 
1032  builder.Scale(GetContentScale().x, GetContentScale().y);
1033 
1034  DlPaint paint;
1035  paint.setColor(DlColor::kRed());
1036  builder.DrawRect(SkRect::MakeLTRB(200, 200, 300, 300), paint);
1037 
1038  paint.setImageFilter(DlImageFilter::MakeMatrix(DlMatrix::MakeScale({2, 2, 1}),
1039  DlImageSampling::kLinear));
1040  builder.SaveLayer(nullptr, &paint);
1041  // Draw a rectangle that would fully cover the parent pass size, but not
1042  // the subpass that it is rendered in.
1043  paint.setColor(DlColor::kGreen());
1044  builder.DrawRect(SkRect::MakeLTRB(0, 0, 400, 400), paint);
1045  // Draw a bigger rectangle to force the subpass to be bigger.
1046 
1047  paint.setColor(DlColor::kRed());
1048  builder.DrawRect(SkRect::MakeLTRB(0, 0, 800, 800), paint);
1049  builder.Restore();
1050 
1051  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1052 }

References x.

◆ TEST_P() [133/497]

impeller::testing::TEST_P ( AiksTest  ,
ClippedBlurFilterRendersCorrectly   
)

Definition at line 407 of file aiks_dl_blur_unittests.cc.

407  {
408  DisplayListBuilder builder;
409  builder.Translate(0, -400);
410  DlPaint paint;
411 
412  Sigma sigma = Radius{120 * 3};
413  paint.setMaskFilter(
414  DlBlurMaskFilter::Make(DlBlurStyle::kNormal, sigma.sigma));
415  paint.setColor(DlColor::kRed());
416 
417  SkPath path = SkPath::Rect(SkRect::MakeLTRB(0, 0, 800, 800));
418  path.addCircle(0, 0, 0.5);
419  builder.DrawPath(path, paint);
420 
421  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
422 }

References impeller::Sigma::sigma.

◆ TEST_P() [134/497]

impeller::testing::TEST_P ( AiksTest  ,
ClippedBlurFilterRendersCorrectlyInteractive   
)

Definition at line 383 of file aiks_dl_blur_unittests.cc.

383  {
384  auto callback = [&]() -> sk_sp<DisplayList> {
385  static PlaygroundPoint playground_point(Point(400, 400), 20,
386  Color::Green());
387  auto point = DrawPlaygroundPoint(playground_point);
388 
389  DisplayListBuilder builder;
390  auto location = point - Point(400, 400);
391  builder.Translate(location.x, location.y);
392 
393  DlPaint paint;
394  Sigma sigma = Radius{120 * 3};
395  paint.setMaskFilter(
396  DlBlurMaskFilter::Make(DlBlurStyle::kNormal, sigma.sigma));
397  paint.setColor(DlColor::kRed());
398 
399  SkPath path = SkPath::Rect(SkRect::MakeLTRB(0, 0, 800, 800));
400  path.addCircle(0, 0, 0.5);
401  builder.DrawPath(path, paint);
402  return builder.Build();
403  };
404  ASSERT_TRUE(OpenPlaygroundHere(callback));
405 }
Point DrawPlaygroundPoint(PlaygroundPoint &point)
Definition: widgets.cc:9

References impeller::DrawPlaygroundPoint(), impeller::Color::Green(), and impeller::Sigma::sigma.

◆ TEST_P() [135/497]

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 }

◆ TEST_P() [136/497]

impeller::testing::TEST_P ( AiksTest  ,
CollapsedDrawPaintInSubpass   
)

Definition at line 50 of file aiks_dl_unittests.cc.

50  {
51  DisplayListBuilder builder;
52 
53  DlPaint paint;
54  paint.setColor(DlColor::kYellow());
55  paint.setBlendMode(DlBlendMode::kSrc);
56  builder.DrawPaint(paint);
57 
58  DlPaint save_paint;
59  save_paint.setBlendMode(DlBlendMode::kMultiply);
60  builder.SaveLayer(nullptr, &save_paint);
61 
62  DlPaint draw_paint;
63  draw_paint.setColor(DlColor::kCornflowerBlue().modulateOpacity(0.75f));
64  builder.DrawPaint(draw_paint);
65 
66  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
67 }

◆ TEST_P() [137/497]

impeller::testing::TEST_P ( AiksTest  ,
CollapsedDrawPaintInSubpassBackdropFilter   
)

Definition at line 69 of file aiks_dl_unittests.cc.

69  {
70  // Bug: https://github.com/flutter/flutter/issues/131576
71  DisplayListBuilder builder;
72 
73  DlPaint paint;
74  paint.setColor(DlColor::kYellow());
75  paint.setBlendMode(DlBlendMode::kSrc);
76  builder.DrawPaint(paint);
77 
78  auto filter = DlImageFilter::MakeBlur(20.0, 20.0, DlTileMode::kDecal);
79  builder.SaveLayer(nullptr, nullptr, filter.get());
80 
81  DlPaint draw_paint;
82  draw_paint.setColor(DlColor::kCornflowerBlue());
83  builder.DrawPaint(draw_paint);
84 
85  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
86 }

◆ TEST_P() [138/497]

impeller::testing::TEST_P ( AiksTest  ,
ColorFilterAdvancedBlend   
)

Definition at line 251 of file aiks_dl_blend_unittests.cc.

251  {
252  bool has_color_filter = true;
253  auto callback = [&]() -> sk_sp<DisplayList> {
254  if (AiksTest::ImGuiBegin("Controls", nullptr,
255  ImGuiWindowFlags_AlwaysAutoResize)) {
256  ImGui::Checkbox("has color filter", &has_color_filter);
257  ImGui::End();
258  }
259 
260  DisplayListBuilder builder;
261  builder.Scale(GetContentScale().x, GetContentScale().y);
262 
263  auto src_image =
264  DlImageImpeller::Make(CreateTextureForFixture("blend_mode_src.png"));
265  auto dst_image =
266  DlImageImpeller::Make(CreateTextureForFixture("blend_mode_dst.png"));
267 
268  std::vector<DlBlendMode> blend_modes = {
269  DlBlendMode::kScreen, DlBlendMode::kOverlay,
270  DlBlendMode::kDarken, DlBlendMode::kLighten,
271  DlBlendMode::kColorDodge, DlBlendMode::kColorBurn,
272  DlBlendMode::kHardLight, DlBlendMode::kSoftLight,
273  DlBlendMode::kDifference, DlBlendMode::kExclusion,
274  DlBlendMode::kMultiply, DlBlendMode::kHue,
275  DlBlendMode::kSaturation, DlBlendMode::kColor,
276  DlBlendMode::kLuminosity,
277  };
278 
279  for (uint32_t i = 0; i < blend_modes.size(); ++i) {
280  builder.Save();
281  builder.Translate((i % 5) * 200, (i / 5) * 200);
282  builder.Scale(0.4, 0.4);
283  {
284  DlPaint dstPaint;
285  builder.DrawImage(dst_image, SkPoint{0, 0},
286  DlImageSampling::kMipmapLinear, &dstPaint);
287  }
288  {
289  DlPaint srcPaint;
290  srcPaint.setBlendMode(blend_modes[i]);
291  if (has_color_filter) {
292  std::shared_ptr<const DlColorFilter> color_filter =
293  DlColorFilter::MakeBlend(DlColor::RGBA(0.9, 0.5, 0.0, 1.0),
294  DlBlendMode::kSrcIn);
295  srcPaint.setColorFilter(color_filter);
296  }
297  builder.DrawImage(src_image, SkPoint{0, 0},
298  DlImageSampling::kMipmapLinear, &srcPaint);
299  }
300  builder.Restore();
301  }
302  return builder.Build();
303  };
304  ASSERT_TRUE(OpenPlaygroundHere(callback));
305 }

References impeller::AiksPlayground::ImGuiBegin(), impeller::DlImageImpeller::Make(), and x.

◆ TEST_P() [139/497]

impeller::testing::TEST_P ( AiksTest  ,
ColorFilterAdvancedBlendNoFbFetch   
)

Definition at line 310 of file aiks_dl_blend_unittests.cc.

310  {
311  if (GetParam() != PlaygroundBackend::kMetal) {
312  GTEST_SKIP()
313  << "This backend doesn't yet support setting device capabilities.";
314  }
315  if (!WillRenderSomething()) {
316  GTEST_SKIP() << "This test requires playgrounds.";
317  }
318 
319  std::shared_ptr<const Capabilities> old_capabilities =
320  GetContext()->GetCapabilities();
321  auto mock_capabilities = std::make_shared<MockCapabilities>();
322  EXPECT_CALL(*mock_capabilities, SupportsFramebufferFetch())
323  .Times(::testing::AtLeast(1))
324  .WillRepeatedly(::testing::Return(false));
325  FLT_FORWARD(mock_capabilities, old_capabilities, GetDefaultColorFormat);
326  FLT_FORWARD(mock_capabilities, old_capabilities, GetDefaultStencilFormat);
327  FLT_FORWARD(mock_capabilities, old_capabilities,
328  GetDefaultDepthStencilFormat);
329  FLT_FORWARD(mock_capabilities, old_capabilities, SupportsOffscreenMSAA);
330  FLT_FORWARD(mock_capabilities, old_capabilities,
331  SupportsImplicitResolvingMSAA);
332  FLT_FORWARD(mock_capabilities, old_capabilities, SupportsReadFromResolve);
333  FLT_FORWARD(mock_capabilities, old_capabilities, SupportsSSBO);
334  FLT_FORWARD(mock_capabilities, old_capabilities, SupportsCompute);
335  FLT_FORWARD(mock_capabilities, old_capabilities,
336  SupportsTextureToTextureBlits);
337  FLT_FORWARD(mock_capabilities, old_capabilities, GetDefaultGlyphAtlasFormat);
338  FLT_FORWARD(mock_capabilities, old_capabilities, SupportsTriangleFan);
339  FLT_FORWARD(mock_capabilities, old_capabilities,
340  SupportsDecalSamplerAddressMode);
341  FLT_FORWARD(mock_capabilities, old_capabilities, SupportsPrimitiveRestart);
342  ASSERT_TRUE(SetCapabilities(mock_capabilities).ok());
343 
344  bool has_color_filter = true;
345  auto callback = [&]() -> sk_sp<DisplayList> {
346  if (AiksTest::ImGuiBegin("Controls", nullptr,
347  ImGuiWindowFlags_AlwaysAutoResize)) {
348  ImGui::Checkbox("has color filter", &has_color_filter);
349  ImGui::End();
350  }
351 
352  DisplayListBuilder builder;
353  builder.Scale(GetContentScale().x, GetContentScale().y);
354 
355  auto src_image =
356  DlImageImpeller::Make(CreateTextureForFixture("blend_mode_src.png"));
357  auto dst_image =
358  DlImageImpeller::Make(CreateTextureForFixture("blend_mode_dst.png"));
359 
360  std::vector<DlBlendMode> blend_modes = {
361  DlBlendMode::kScreen, DlBlendMode::kOverlay,
362  DlBlendMode::kDarken, DlBlendMode::kLighten,
363  DlBlendMode::kColorDodge, DlBlendMode::kColorBurn,
364  DlBlendMode::kHardLight, DlBlendMode::kSoftLight,
365  DlBlendMode::kDifference, DlBlendMode::kExclusion,
366  DlBlendMode::kMultiply, DlBlendMode::kHue,
367  DlBlendMode::kSaturation, DlBlendMode::kColor,
368  DlBlendMode::kLuminosity,
369  };
370 
371  for (uint32_t i = 0; i < blend_modes.size(); ++i) {
372  builder.Save();
373  builder.Translate((i % 5) * 200, (i / 5) * 200);
374  builder.Scale(0.4, 0.4);
375  {
376  DlPaint dstPaint;
377  builder.DrawImage(dst_image, SkPoint{0, 0},
378  DlImageSampling::kMipmapLinear, &dstPaint);
379  }
380  {
381  DlPaint srcPaint;
382  srcPaint.setBlendMode(blend_modes[i]);
383  if (has_color_filter) {
384  std::shared_ptr<const DlColorFilter> color_filter =
385  DlColorFilter::MakeBlend(DlColor::RGBA(0.9, 0.5, 0.0, 1.0),
386  DlBlendMode::kMultiply);
387  srcPaint.setColorFilter(color_filter);
388  }
389  builder.DrawImage(src_image, SkPoint{0, 0},
390  DlImageSampling::kMipmapLinear, &srcPaint);
391  }
392  builder.Restore();
393  }
394  return builder.Build();
395  };
396  ASSERT_TRUE(OpenPlaygroundHere(callback));
397 }

References impeller::AiksPlayground::ImGuiBegin(), impeller::kMetal, impeller::DlImageImpeller::Make(), and x.

◆ TEST_P() [140/497]

impeller::testing::TEST_P ( AiksTest  ,
ColorFilterBlend   
)

Definition at line 199 of file aiks_dl_blend_unittests.cc.

199  {
200  bool has_color_filter = true;
201  auto callback = [&]() -> sk_sp<DisplayList> {
202  if (AiksTest::ImGuiBegin("Controls", nullptr,
203  ImGuiWindowFlags_AlwaysAutoResize)) {
204  ImGui::Checkbox("has color filter", &has_color_filter);
205  ImGui::End();
206  }
207 
208  DisplayListBuilder builder;
209  builder.Scale(GetContentScale().x, GetContentScale().y);
210 
211  auto src_image =
212  DlImageImpeller::Make(CreateTextureForFixture("blend_mode_src.png"));
213  auto dst_image =
214  DlImageImpeller::Make(CreateTextureForFixture("blend_mode_dst.png"));
215 
216  std::vector<DlBlendMode> blend_modes = {
217  DlBlendMode::kSrc, DlBlendMode::kSrcATop, DlBlendMode::kSrcOver,
218  DlBlendMode::kSrcIn, DlBlendMode::kSrcOut, DlBlendMode::kDst,
219  DlBlendMode::kDstATop, DlBlendMode::kDstOver, DlBlendMode::kDstIn,
220  DlBlendMode::kDstOut, DlBlendMode::kClear, DlBlendMode::kXor};
221 
222  for (uint32_t i = 0; i < blend_modes.size(); ++i) {
223  builder.Save();
224  builder.Translate((i % 5) * 200, (i / 5) * 200);
225  builder.Scale(0.4, 0.4);
226  {
227  DlPaint dstPaint;
228  builder.DrawImage(dst_image, SkPoint{0, 0},
229  DlImageSampling::kMipmapLinear, &dstPaint);
230  }
231  {
232  DlPaint srcPaint;
233  srcPaint.setBlendMode(blend_modes[i]);
234  if (has_color_filter) {
235  std::shared_ptr<const DlColorFilter> color_filter =
236  DlColorFilter::MakeBlend(DlColor::RGBA(0.9, 0.5, 0.0, 1.0),
237  DlBlendMode::kSrcIn);
238  srcPaint.setColorFilter(color_filter);
239  }
240  builder.DrawImage(src_image, SkPoint{0, 0},
241  DlImageSampling::kMipmapLinear, &srcPaint);
242  }
243  builder.Restore();
244  }
245  return builder.Build();
246  };
247  ASSERT_TRUE(OpenPlaygroundHere(callback));
248 }

References impeller::AiksPlayground::ImGuiBegin(), impeller::DlImageImpeller::Make(), and x.

◆ TEST_P() [141/497]

impeller::testing::TEST_P ( AiksTest  ,
ColorMatrixFilterSubpassCollapseOptimization   
)

Definition at line 88 of file aiks_dl_unittests.cc.

88  {
89  DisplayListBuilder builder(GetCullRect(GetWindowSize()));
90 
91  const float matrix[20] = {
92  -1.0, 0, 0, 1.0, 0, //
93  0, -1.0, 0, 1.0, 0, //
94  0, 0, -1.0, 1.0, 0, //
95  1.0, 1.0, 1.0, 1.0, 0 //
96  };
97  auto filter = DlColorFilter::MakeMatrix(matrix);
98 
99  DlPaint paint;
100  paint.setColorFilter(filter);
101  builder.SaveLayer(nullptr, &paint);
102 
103  builder.Translate(500, 300);
104  builder.Rotate(120); // 120 deg
105 
106  DlPaint draw_paint;
107  draw_paint.setColor(DlColor::kBlue());
108  builder.DrawRect(SkRect::MakeXYWH(100, 100, 200, 200), draw_paint);
109 
110  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
111 }

◆ TEST_P() [142/497]

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 775 of file aiks_dl_blend_unittests.cc.

775  {
776  // Compare with https://fiddle.skia.org/c/@BlendModes
777 
778  BlendModeSelection blend_modes = GetBlendModeSelection();
779 
780  auto draw_color_wheel = [](DisplayListBuilder& builder) -> void {
781  /// color_wheel_sampler: r=0 -> fuchsia, r=2pi/3 -> yellow, r=4pi/3 ->
782  /// cyan domain: r >= 0 (because modulo used is non euclidean)
783  auto color_wheel_sampler = [](Radians r) {
784  Scalar x = r.radians / k2Pi + 1;
785 
786  // https://www.desmos.com/calculator/6nhjelyoaj
787  auto color_cycle = [](Scalar x) {
788  Scalar cycle = std::fmod(x, 6.0f);
789  return std::max(0.0f, std::min(1.0f, 2 - std::abs(2 - cycle)));
790  };
791  return Color(color_cycle(6 * x + 1), //
792  color_cycle(6 * x - 1), //
793  color_cycle(6 * x - 3), //
794  1);
795  };
796 
797  DlPaint paint;
798  paint.setBlendMode(DlBlendMode::kSrcOver);
799 
800  // Draw a fancy color wheel for the backdrop.
801  // https://www.desmos.com/calculator/xw7kafthwd
802  const int max_dist = 900;
803  for (int i = 0; i <= 900; i++) {
804  Radians r(kPhi / k2Pi * i);
805  Scalar distance = r.radians / std::powf(4.12, 0.0026 * r.radians);
806  Scalar normalized_distance = static_cast<Scalar>(i) / max_dist;
807 
808  auto color = color_wheel_sampler(r).WithAlpha(1.0f - normalized_distance);
809  paint.setColor(
810  DlColor::RGBA(color.red, color.green, color.blue, color.alpha));
811  SkPoint position = SkPoint::Make(distance * std::sin(r.radians),
812  -distance * std::cos(r.radians));
813 
814  builder.DrawCircle(position, 9 + normalized_distance * 3, paint);
815  }
816  };
817 
818  auto callback = [&]() -> sk_sp<DisplayList> {
819  // UI state.
820  static bool cache_the_wheel = true;
821  static int current_blend_index = 3;
822  static float dst_alpha = 1;
823  static float src_alpha = 1;
824  static DlColor color0 = DlColor::kRed();
825  static DlColor color1 = DlColor::kGreen();
826  static DlColor color2 = DlColor::kBlue();
827 
828  if (AiksTest::ImGuiBegin("Controls", nullptr,
829  ImGuiWindowFlags_AlwaysAutoResize)) {
830  ImGui::Checkbox("Cache the wheel", &cache_the_wheel);
831  ImGui::ListBox("Blending mode", &current_blend_index,
832  blend_modes.blend_mode_names.data(),
833  blend_modes.blend_mode_names.size());
834  ImGui::SliderFloat("Source alpha", &src_alpha, 0, 1);
835  ImGui::ColorEdit4("Color A", reinterpret_cast<float*>(&color0));
836  ImGui::ColorEdit4("Color B", reinterpret_cast<float*>(&color1));
837  ImGui::ColorEdit4("Color C", reinterpret_cast<float*>(&color2));
838  ImGui::SliderFloat("Destination alpha", &dst_alpha, 0, 1);
839  ImGui::End();
840  }
841 
842  DisplayListBuilder builder;
843 
844  DlPaint paint;
845  paint.setColor(DlColor::kWhite().withAlpha(dst_alpha * 255));
846  paint.setBlendMode(DlBlendMode::kSrc);
847  builder.SaveLayer(nullptr, &paint);
848  {
849  DlPaint paint;
850  paint.setColor(DlColor::kWhite());
851  builder.DrawPaint(paint);
852 
853  builder.SaveLayer(nullptr, nullptr);
854  builder.Scale(GetContentScale().x, GetContentScale().y);
855  builder.Translate(500, 400);
856  builder.Scale(3, 3);
857  draw_color_wheel(builder);
858  builder.Restore();
859  }
860  builder.Restore();
861 
862  builder.Scale(GetContentScale().x, GetContentScale().y);
863  builder.Translate(500, 400);
864  builder.Scale(3, 3);
865 
866  // Draw 3 circles to a subpass and blend it in.
867  DlPaint save_paint;
868  save_paint.setColor(DlColor::kWhite().withAlpha(src_alpha * 255));
869  save_paint.setBlendMode(static_cast<DlBlendMode>(
870  blend_modes.blend_mode_values[current_blend_index]));
871  builder.SaveLayer(nullptr, &save_paint);
872  {
873  DlPaint paint;
874  paint.setBlendMode(DlBlendMode::kPlus);
875  const Scalar x = std::sin(k2Pi / 3);
876  const Scalar y = -std::cos(k2Pi / 3);
877  paint.setColor(color0);
878  builder.DrawCircle(SkPoint::Make(-x * 45, y * 45), 65, paint);
879  paint.setColor(color1);
880  builder.DrawCircle(SkPoint::Make(0, -45), 65, paint);
881  paint.setColor(color2);
882  builder.DrawCircle(SkPoint::Make(x * 45, y * 45), 65, paint);
883  }
884  builder.Restore();
885 
886  return builder.Build();
887  };
888 
889  ASSERT_TRUE(OpenPlaygroundHere(callback));
890 }
constexpr float kPhi
Definition: constants.h:53

References impeller::testing::BlendModeSelection::blend_mode_names, impeller::testing::BlendModeSelection::blend_mode_values, impeller::saturated::distance, GetBlendModeSelection(), impeller::AiksPlayground::ImGuiBegin(), impeller::k2Pi, impeller::kPhi, impeller::Radians::radians, and x.

◆ TEST_P() [143/497]

impeller::testing::TEST_P ( AiksTest  ,
CoordinateConversionsAreCorrect   
)

Definition at line 1126 of file aiks_dl_basic_unittests.cc.

1126  {
1127  DisplayListBuilder builder;
1128 
1129  // Render a texture directly.
1130  {
1131  auto image = DlImageImpeller::Make(CreateTextureForFixture("kalimba.jpg"));
1132 
1133  builder.Save();
1134  builder.Translate(100, 200);
1135  builder.Scale(0.5, 0.5);
1136  builder.DrawImage(image, SkPoint::Make(100.0, 100.0),
1137  DlImageSampling::kNearestNeighbor);
1138  builder.Restore();
1139  }
1140 
1141  // Render an offscreen rendered texture.
1142  {
1143  DlPaint alpha;
1144  alpha.setColor(DlColor::kRed().modulateOpacity(0.5));
1145 
1146  builder.SaveLayer(nullptr, &alpha);
1147 
1148  DlPaint paint;
1149  paint.setColor(DlColor::kRed());
1150  builder.DrawRect(SkRect::MakeXYWH(000, 000, 100, 100), paint);
1151  paint.setColor(DlColor::kGreen());
1152  builder.DrawRect(SkRect::MakeXYWH(020, 020, 100, 100), paint);
1153  paint.setColor(DlColor::kBlue());
1154  builder.DrawRect(SkRect::MakeXYWH(040, 040, 100, 100), paint);
1155 
1156  builder.Restore();
1157  }
1158 
1159  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1160 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [144/497]

impeller::testing::TEST_P ( AiksTest  ,
CoverageOriginShouldBeAccountedForInSubpasses   
)

Definition at line 1309 of file aiks_dl_basic_unittests.cc.

1309  {
1310  auto callback = [&]() -> sk_sp<DisplayList> {
1311  DisplayListBuilder builder;
1312  builder.Scale(GetContentScale().x, GetContentScale().y);
1313 
1314  DlPaint alpha;
1315  alpha.setColor(DlColor::kRed().modulateOpacity(0.5));
1316 
1317  auto current = Point{25, 25};
1318  const auto offset = Point{25, 25};
1319  const auto size = Size(100, 100);
1320 
1321  static PlaygroundPoint point_a(Point(40, 40), 10, Color::White());
1322  static PlaygroundPoint point_b(Point(160, 160), 10, Color::White());
1323  auto [b0, b1] = DrawPlaygroundLine(point_a, point_b);
1324  SkRect bounds = SkRect::MakeLTRB(b0.x, b0.y, b1.x, b1.y);
1325 
1326  DlPaint stroke_paint;
1327  stroke_paint.setColor(DlColor::kYellow());
1328  stroke_paint.setStrokeWidth(5);
1329  stroke_paint.setDrawStyle(DlDrawStyle::kStroke);
1330  builder.DrawRect(bounds, stroke_paint);
1331 
1332  builder.SaveLayer(&bounds, &alpha);
1333 
1334  DlPaint paint;
1335  paint.setColor(DlColor::kRed());
1336  builder.DrawRect(
1337  SkRect::MakeXYWH(current.x, current.y, size.width, size.height), paint);
1338 
1339  paint.setColor(DlColor::kGreen());
1340  current += offset;
1341  builder.DrawRect(
1342  SkRect::MakeXYWH(current.x, current.y, size.width, size.height), paint);
1343 
1344  paint.setColor(DlColor::kBlue());
1345  current += offset;
1346  builder.DrawRect(
1347  SkRect::MakeXYWH(current.x, current.y, size.width, size.height), paint);
1348 
1349  builder.Restore();
1350 
1351  return builder.Build();
1352  };
1353 
1354  ASSERT_TRUE(OpenPlaygroundHere(callback));
1355 }

References impeller::DrawPlaygroundLine(), offset, and impeller::Color::White().

◆ TEST_P() [145/497]

impeller::testing::TEST_P ( AiksTest  ,
DepthValuesForLineMode   
)

Definition at line 995 of file aiks_dl_unittests.cc.

995  {
996  // Ensures that the additional draws created by line/polygon mode all
997  // have the same depth values.
998  DisplayListBuilder builder;
999 
1000  SkPath path = SkPath::Circle(100, 100, 100);
1001 
1002  builder.DrawPath(path, DlPaint()
1003  .setColor(DlColor::kRed())
1004  .setDrawStyle(DlDrawStyle::kStroke)
1005  .setStrokeWidth(5));
1006  builder.Save();
1007  builder.ClipPath(path);
1008 
1009  std::vector<DlPoint> points = {
1010  DlPoint::MakeXY(0, -200), DlPoint::MakeXY(400, 200),
1011  DlPoint::MakeXY(0, -100), DlPoint::MakeXY(400, 300),
1012  DlPoint::MakeXY(0, 0), DlPoint::MakeXY(400, 400),
1013  DlPoint::MakeXY(0, 100), DlPoint::MakeXY(400, 500),
1014  DlPoint::MakeXY(0, 150), DlPoint::MakeXY(400, 600)};
1015 
1016  builder.DrawPoints(DisplayListBuilder::PointMode::kLines, points.size(),
1017  points.data(),
1018  DlPaint().setColor(DlColor::kBlue()).setStrokeWidth(10));
1019  builder.Restore();
1020 
1021  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1022 }

◆ TEST_P() [146/497]

impeller::testing::TEST_P ( AiksTest  ,
DepthValuesForPolygonMode   
)

Definition at line 1024 of file aiks_dl_unittests.cc.

1024  {
1025  // Ensures that the additional draws created by line/polygon mode all
1026  // have the same depth values.
1027  DisplayListBuilder builder;
1028 
1029  SkPath path = SkPath::Circle(100, 100, 100);
1030 
1031  builder.DrawPath(path, DlPaint()
1032  .setColor(DlColor::kRed())
1033  .setDrawStyle(DlDrawStyle::kStroke)
1034  .setStrokeWidth(5));
1035  builder.Save();
1036  builder.ClipPath(path);
1037 
1038  std::vector<DlPoint> points = {
1039  DlPoint::MakeXY(0, -200), DlPoint::MakeXY(400, 200),
1040  DlPoint::MakeXY(0, -100), DlPoint::MakeXY(400, 300),
1041  DlPoint::MakeXY(0, 0), DlPoint::MakeXY(400, 400),
1042  DlPoint::MakeXY(0, 100), DlPoint::MakeXY(400, 500),
1043  DlPoint::MakeXY(0, 150), DlPoint::MakeXY(400, 600)};
1044 
1045  builder.DrawPoints(DisplayListBuilder::PointMode::kPolygon, points.size(),
1046  points.data(),
1047  DlPaint().setColor(DlColor::kBlue()).setStrokeWidth(10));
1048  builder.Restore();
1049 
1050  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1051 }

◆ TEST_P() [147/497]

impeller::testing::TEST_P ( AiksTest  ,
DestructiveBlendColorFilterFloodsClip   
)

Definition at line 892 of file aiks_dl_blend_unittests.cc.

892  {
893  DisplayListBuilder builder;
894 
895  DlPaint paint;
896  paint.setColor(DlColor::kBlue());
897  builder.DrawPaint(paint);
898 
899  DlPaint save_paint;
900  save_paint.setColorFilter(
901  DlColorFilter::MakeBlend(DlColor::kRed(), DlBlendMode::kSrc));
902  builder.SaveLayer(nullptr, &save_paint);
903  builder.Restore();
904 
905  // Should be solid red as the destructive color filter floods the clip.
906  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
907 }

◆ TEST_P() [148/497]

impeller::testing::TEST_P ( AiksTest  ,
DifferenceClipsMustRenderIdenticallyAcrossBackends   
)

Definition at line 546 of file aiks_dl_text_unittests.cc.

546  {
547  DisplayListBuilder builder;
548 
549  DlPaint paint;
550  DlColor clear_color(1.0, 0.5, 0.5, 0.5, DlColorSpace::kSRGB);
551  paint.setColor(clear_color);
552  builder.DrawPaint(paint);
553 
554  DlMatrix identity = {
555  1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0,
556  0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0,
557  };
558  builder.Save();
559  builder.Transform(identity);
560 
561  DlRect frame = DlRect::MakeLTRB(1.0, 1.0, 1278.0, 763.0);
562  DlColor white(1.0, 1.0, 1.0, 1.0, DlColorSpace::kSRGB);
563  paint.setColor(white);
564  builder.DrawRect(frame, paint);
565 
566  builder.Save();
567  builder.ClipRect(frame, DlCanvas::ClipOp::kIntersect);
568 
569  DlMatrix rect_xform = {
570  0.8241262, 0.56640625, 0.0, 0.0, -0.56640625, 0.8241262, 0.0, 0.0,
571  0.0, 0.0, 1.0, 0.0, 271.1137, 489.4733, 0.0, 1.0,
572  };
573  builder.Save();
574  builder.Transform(rect_xform);
575 
576  DlRect rect = DlRect::MakeLTRB(0.0, 0.0, 100.0, 100.0);
577  DlColor bluish(1.0, 0.184, 0.501, 0.929, DlColorSpace::kSRGB);
578  paint.setColor(bluish);
579  DlRoundRect rrect = DlRoundRect::MakeRectRadius(rect, 18.0);
580  builder.DrawRoundRect(rrect, paint);
581 
582  builder.Save();
583  builder.ClipRect(rect, DlCanvas::ClipOp::kIntersect);
584  builder.Restore();
585 
586  builder.Restore();
587 
588  DlMatrix path_xform = {
589  1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0,
590  0.0, 0.0, 1.0, 0.0, 675.0, 279.5, 0.0, 1.0,
591  };
592  builder.Save();
593  builder.Transform(path_xform);
594 
595  SkPath path;
596  path.moveTo(87.5, 349.5);
597  path.lineTo(25.0, 29.5);
598  path.lineTo(150.0, 118.0);
599  path.lineTo(25.0, 118.0);
600  path.lineTo(150.0, 29.5);
601  path.close();
602 
603  DlColor fill_color(1.0, 1.0, 0.0, 0.0, DlColorSpace::kSRGB);
604  DlColor stroke_color(1.0, 0.0, 0.0, 0.0, DlColorSpace::kSRGB);
605  paint.setColor(fill_color);
606  paint.setDrawStyle(DlDrawStyle::kFill);
607  builder.DrawPath(DlPath(path), paint);
608 
609  paint.setColor(stroke_color);
610  paint.setStrokeWidth(2.0);
611  paint.setDrawStyle(DlDrawStyle::kStroke);
612  builder.DrawPath(path, paint);
613 
614  builder.Restore();
615  builder.Restore();
616  builder.Restore();
617 
618  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
619 }
flutter::DlRoundRect DlRoundRect
Definition: dl_dispatcher.h:27
flutter::DlPath DlPath
Definition: dl_dispatcher.h:28

◆ TEST_P() [149/497]

impeller::testing::TEST_P ( AiksTest  ,
DispatcherDoesNotCullPerspectiveTransformedChildDisplayLists   
)

Definition at line 881 of file aiks_dl_unittests.cc.

881  {
882  flutter::DisplayListBuilder sub_builder(true);
883  sub_builder.DrawRect(SkRect::MakeXYWH(0, 0, 50, 50),
884  flutter::DlPaint(flutter::DlColor::kRed()));
885  auto display_list = sub_builder.Build();
886 
887  AiksContext context(GetContext(), nullptr);
888  RenderTarget render_target =
889  context.GetContentContext().GetRenderTargetCache()->CreateOffscreen(
890  *context.GetContext(), {2400, 1800}, 1);
891 
892  DisplayListBuilder builder;
893 
894  builder.Scale(2.0, 2.0);
895  builder.Translate(-93.0, 0.0);
896 
897  // clang-format off
898  builder.TransformFullPerspective(
899  0.8, -0.2, -0.1, -0.0,
900  0.0, 1.0, 0.0, 0.0,
901  1.4, 1.3, 1.0, 0.0,
902  63.2, 65.3, 48.6, 1.1
903  );
904  // clang-format on
905  builder.Translate(35.0, 75.0);
906  builder.DrawDisplayList(display_list, 1.0f);
907 
908  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
909 }

References impeller::AiksContext::GetContentContext(), impeller::AiksContext::GetContext(), and impeller::ContentContext::GetRenderTargetCache().

◆ TEST_P() [150/497]

impeller::testing::TEST_P ( AiksTest  ,
DisplayListToTextureAllocationFailure   
)

Definition at line 1127 of file aiks_dl_unittests.cc.

1127  {
1128  ScopedValidationDisable disable_validations;
1129  DisplayListBuilder builder;
1130 
1131  AiksContext aiks_context(GetContext(), nullptr);
1132  // Use intentionally invalid dimensions that would trigger an allocation
1133  // failure.
1134  auto texture =
1135  DisplayListToTexture(builder.Build(), ISize{0, 0}, aiks_context);
1136 
1137  EXPECT_EQ(texture, nullptr);
1138 }

References impeller::DisplayListToTexture().

◆ TEST_P() [151/497]

impeller::testing::TEST_P ( AiksTest  ,
DlAtlasGeometryBlend   
)

Definition at line 198 of file aiks_dl_atlas_unittests.cc.

198  {
199  auto [texture_coordinates, transforms, atlas] = CreateTestData(this);
200 
201  std::vector<DlColor> colors;
202  colors.reserve(texture_coordinates.size());
203  for (auto i = 0u; i < texture_coordinates.size(); i++) {
204  colors.push_back(DlColor::ARGB(0.5, 1, 1, 1));
205  }
206  DlAtlasGeometry geom(atlas->impeller_texture(), transforms.data(),
207  texture_coordinates.data(), colors.data(),
208  transforms.size(), BlendMode::kSourceOver, {},
209  std::nullopt);
210 
211  EXPECT_TRUE(geom.ShouldUseBlend());
212  EXPECT_FALSE(geom.ShouldSkip());
213 
214  ContentContext context(GetContext(), nullptr);
215  auto vertex_buffer =
216  geom.CreateBlendVertexBuffer(context.GetTransientsBuffer());
217 
218  EXPECT_EQ(vertex_buffer.index_type, IndexType::kNone);
219  EXPECT_EQ(vertex_buffer.vertex_count, texture_coordinates.size() * 6);
220 }

References impeller::DlAtlasGeometry::CreateBlendVertexBuffer(), impeller::ContentContext::GetTransientsBuffer(), impeller::kNone, impeller::kSourceOver, impeller::DlAtlasGeometry::ShouldSkip(), and impeller::DlAtlasGeometry::ShouldUseBlend().

◆ TEST_P() [152/497]

impeller::testing::TEST_P ( AiksTest  ,
DlAtlasGeometryColorButNoBlend   
)

Definition at line 222 of file aiks_dl_atlas_unittests.cc.

222  {
223  auto [texture_coordinates, transforms, atlas] = CreateTestData(this);
224 
225  std::vector<DlColor> colors;
226  colors.reserve(texture_coordinates.size());
227  for (auto i = 0u; i < texture_coordinates.size(); i++) {
228  colors.push_back(DlColor::ARGB(0.5, 1, 1, 1));
229  }
230  DlAtlasGeometry geom(atlas->impeller_texture(), transforms.data(),
231  texture_coordinates.data(), colors.data(),
232  transforms.size(), BlendMode::kSource, {}, std::nullopt);
233 
234  // Src blend mode means that colors would be ignored, even if provided.
235  EXPECT_FALSE(geom.ShouldUseBlend());
236  EXPECT_FALSE(geom.ShouldSkip());
237 }

References impeller::kSource, impeller::DlAtlasGeometry::ShouldSkip(), and impeller::DlAtlasGeometry::ShouldUseBlend().

◆ TEST_P() [153/497]

impeller::testing::TEST_P ( AiksTest  ,
DlAtlasGeometryNoBlend   
)

Definition at line 180 of file aiks_dl_atlas_unittests.cc.

180  {
181  auto [texture_coordinates, transforms, atlas] = CreateTestData(this);
182 
183  DlAtlasGeometry geom(atlas->impeller_texture(), transforms.data(),
184  texture_coordinates.data(), nullptr, transforms.size(),
185  BlendMode::kSourceOver, {}, std::nullopt);
186 
187  EXPECT_FALSE(geom.ShouldUseBlend());
188  EXPECT_FALSE(geom.ShouldSkip());
189 
190  ContentContext context(GetContext(), nullptr);
191  auto vertex_buffer =
192  geom.CreateSimpleVertexBuffer(context.GetTransientsBuffer());
193 
194  EXPECT_EQ(vertex_buffer.index_type, IndexType::kNone);
195  EXPECT_EQ(vertex_buffer.vertex_count, texture_coordinates.size() * 6);
196 }

References impeller::DlAtlasGeometry::CreateSimpleVertexBuffer(), impeller::ContentContext::GetTransientsBuffer(), impeller::kNone, impeller::kSourceOver, impeller::DlAtlasGeometry::ShouldSkip(), and impeller::DlAtlasGeometry::ShouldUseBlend().

◆ TEST_P() [154/497]

impeller::testing::TEST_P ( AiksTest  ,
DlAtlasGeometrySkip   
)

Definition at line 239 of file aiks_dl_atlas_unittests.cc.

239  {
240  auto [texture_coordinates, transforms, atlas] = CreateTestData(this);
241 
242  std::vector<DlColor> colors;
243  colors.reserve(texture_coordinates.size());
244  for (auto i = 0u; i < texture_coordinates.size(); i++) {
245  colors.push_back(DlColor::ARGB(0.5, 1, 1, 1));
246  }
247  DlAtlasGeometry geom(atlas->impeller_texture(), transforms.data(),
248  texture_coordinates.data(), colors.data(),
249  transforms.size(), BlendMode::kClear, {}, std::nullopt);
250  EXPECT_TRUE(geom.ShouldSkip());
251 }

References impeller::kClear, and impeller::DlAtlasGeometry::ShouldSkip().

◆ TEST_P() [155/497]

impeller::testing::TEST_P ( AiksTest  ,
DrawAdvancedBlendPartlyOffscreen   
)

Definition at line 143 of file aiks_dl_blend_unittests.cc.

143  {
144  DisplayListBuilder builder;
145 
146  DlPaint draw_paint;
147  draw_paint.setColor(DlColor::kBlue());
148  builder.DrawPaint(draw_paint);
149  builder.Scale(2, 2);
150  builder.ClipRect(SkRect::MakeLTRB(0, 0, 200, 200));
151 
152  std::vector<DlColor> colors = {DlColor::RGBA(0.9568, 0.2627, 0.2118, 1.0),
153  DlColor::RGBA(0.1294, 0.5882, 0.9529, 1.0)};
154  std::vector<Scalar> stops = {0.0, 1.0};
155 
156  DlPaint paint;
157  DlMatrix matrix = DlMatrix::MakeScale({0.3, 0.3, 1.0});
158  paint.setColorSource(DlColorSource::MakeLinear(
159  /*start_point=*/{0, 0}, //
160  /*end_point=*/{100, 100}, //
161  /*stop_count=*/colors.size(), //
162  /*colors=*/colors.data(), //
163  /*stops=*/stops.data(), //
164  /*tile_mode=*/DlTileMode::kRepeat, //
165  /*matrix=*/&matrix //
166  ));
167  paint.setBlendMode(DlBlendMode::kLighten);
168 
169  builder.DrawCircle(SkPoint{100, 100}, 100, paint);
170  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
171 }

◆ TEST_P() [156/497]

impeller::testing::TEST_P ( AiksTest  ,
DrawAtlasAdvancedAndTransform   
)

Definition at line 134 of file aiks_dl_atlas_unittests.cc.

134  {
135  DisplayListBuilder builder;
136  // Draws the image as four squares stiched together.
137  auto [texture_coordinates, transforms, atlas] = CreateTestData(this);
138 
139  builder.Scale(0.25, 0.25);
140  builder.DrawAtlas(atlas, transforms.data(), texture_coordinates.data(),
141  /*colors=*/nullptr, /*count=*/4, DlBlendMode::kModulate,
142  DlImageSampling::kNearestNeighbor, /*cullRect=*/nullptr);
143 
144  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
145 }

◆ TEST_P() [157/497]

impeller::testing::TEST_P ( AiksTest  ,
DrawAtlasNoColor   
)

Definition at line 57 of file aiks_dl_atlas_unittests.cc.

57  {
58  DisplayListBuilder builder;
59  auto [texture_coordinates, transforms, atlas] = CreateTestData(this);
60 
61  builder.Scale(GetContentScale().x, GetContentScale().y);
62  builder.DrawAtlas(atlas, transforms.data(), texture_coordinates.data(),
63  /*colors=*/nullptr, /*count=*/4, DlBlendMode::kSrcOver,
64  DlImageSampling::kNearestNeighbor, nullptr);
65 
66  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
67 }

References x.

◆ TEST_P() [158/497]

impeller::testing::TEST_P ( AiksTest  ,
DrawAtlasNoColorFullSize   
)

Definition at line 117 of file aiks_dl_atlas_unittests.cc.

117  {
118  auto atlas = DlImageImpeller::Make(CreateTextureForFixture("bay_bridge.jpg"));
119  auto size = atlas->impeller_texture()->GetSize();
120  std::vector<DlRect> texture_coordinates = {
121  DlRect::MakeLTRB(0, 0, size.width, size.height)};
122  std::vector<RSTransform> transforms = {MakeTranslation(0, 0)};
123 
124  DisplayListBuilder builder;
125  builder.Scale(GetContentScale().x, GetContentScale().y);
126  builder.DrawAtlas(atlas, transforms.data(), texture_coordinates.data(),
127  /*colors=*/nullptr, /*count=*/1, DlBlendMode::kSrcOver,
128  DlImageSampling::kNearestNeighbor, /*cullRect=*/nullptr);
129 
130  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
131 }

References impeller::DlImageImpeller::Make(), and x.

◆ TEST_P() [159/497]

impeller::testing::TEST_P ( AiksTest  ,
DrawAtlasPlusWideGamut   
)

Definition at line 163 of file aiks_dl_atlas_unittests.cc.

163  {
164  DisplayListBuilder builder;
165  EXPECT_EQ(GetContext()->GetCapabilities()->GetDefaultColorFormat(),
166  PixelFormat::kB10G10R10A10XR);
167 
168  // Draws the image as four squares stiched together.
169  auto [texture_coordinates, transforms, atlas] = CreateTestData(this);
170  std::vector<DlColor> colors = {DlColor::kRed(), DlColor::kGreen(),
171  DlColor::kBlue(), DlColor::kYellow()};
172 
173  builder.DrawAtlas(atlas, transforms.data(), texture_coordinates.data(),
174  colors.data(), /*count=*/4, DlBlendMode::kPlus,
175  DlImageSampling::kNearestNeighbor, /*cullRect=*/nullptr);
176 
177  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
178 }

References impeller::kB10G10R10A10XR.

◆ TEST_P() [160/497]

impeller::testing::TEST_P ( AiksTest  ,
DrawAtlasWithColorAdvanced   
)

Definition at line 69 of file aiks_dl_atlas_unittests.cc.

69  {
70  DisplayListBuilder builder;
71  auto [texture_coordinates, transforms, atlas] = CreateTestData(this);
72 
73  std::vector<DlColor> colors = {DlColor::kRed(), DlColor::kGreen(),
74  DlColor::kBlue(), DlColor::kYellow()};
75 
76  builder.Scale(GetContentScale().x, GetContentScale().y);
77  builder.DrawAtlas(atlas, transforms.data(), texture_coordinates.data(),
78  colors.data(), /*count=*/4, DlBlendMode::kModulate,
79  DlImageSampling::kNearestNeighbor, /*cullRect=*/nullptr);
80 
81  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
82 }

References x.

◆ TEST_P() [161/497]

impeller::testing::TEST_P ( AiksTest  ,
DrawAtlasWithColorAdvancedAndTransform   
)

Definition at line 148 of file aiks_dl_atlas_unittests.cc.

148  {
149  DisplayListBuilder builder;
150  // Draws the image as four squares stiched together.
151  auto [texture_coordinates, transforms, atlas] = CreateTestData(this);
152  std::vector<DlColor> colors = {DlColor::kRed(), DlColor::kGreen(),
153  DlColor::kBlue(), DlColor::kYellow()};
154 
155  builder.Scale(0.25, 0.25);
156  builder.DrawAtlas(atlas, transforms.data(), texture_coordinates.data(),
157  colors.data(), /*count=*/4, DlBlendMode::kModulate,
158  DlImageSampling::kNearestNeighbor, /*cullRect=*/nullptr);
159 
160  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
161 }

◆ TEST_P() [162/497]

impeller::testing::TEST_P ( AiksTest  ,
DrawAtlasWithColorSimple   
)

Definition at line 84 of file aiks_dl_atlas_unittests.cc.

84  {
85  DisplayListBuilder builder;
86  // Draws the image as four squares stiched together.
87  auto [texture_coordinates, transforms, atlas] = CreateTestData(this);
88 
89  std::vector<DlColor> colors = {DlColor::kRed(), DlColor::kGreen(),
90  DlColor::kBlue(), DlColor::kYellow()};
91 
92  builder.Scale(GetContentScale().x, GetContentScale().y);
93  builder.DrawAtlas(atlas, transforms.data(), texture_coordinates.data(),
94  colors.data(), /*count=*/4, DlBlendMode::kSrcATop,
95  DlImageSampling::kNearestNeighbor, /*cullRect=*/nullptr);
96 
97  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
98 }

References x.

◆ TEST_P() [163/497]

impeller::testing::TEST_P ( AiksTest  ,
DrawAtlasWithOpacity   
)

Definition at line 100 of file aiks_dl_atlas_unittests.cc.

100  {
101  DisplayListBuilder builder;
102  // Draws the image as four squares stiched together slightly
103  // opaque
104  auto [texture_coordinates, transforms, atlas] = CreateTestData(this);
105 
106  DlPaint paint;
107  paint.setAlpha(128);
108  builder.Scale(GetContentScale().x, GetContentScale().y);
109  builder.DrawAtlas(atlas, transforms.data(), texture_coordinates.data(),
110  /*colors=*/nullptr, 4, DlBlendMode::kSrcOver,
111  DlImageSampling::kNearestNeighbor, /*cullRect=*/nullptr,
112  &paint);
113 
114  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
115 }

References x.

◆ TEST_P() [164/497]

impeller::testing::TEST_P ( AiksTest  ,
DrawImageRectSrcOutsideBounds   
)

Definition at line 235 of file aiks_dl_basic_unittests.cc.

235  {
236  DisplayListBuilder builder;
237  auto image = DlImageImpeller::Make(CreateTextureForFixture("kalimba.jpg"));
238 
239  // Use a source rect that is partially outside the bounds of the image.
240  auto source_rect = SkRect::MakeXYWH(
241  image->dimensions().fWidth * 0.25f, image->dimensions().fHeight * 0.4f,
242  image->dimensions().fWidth, image->dimensions().fHeight);
243 
244  auto dest_rect = SkRect::MakeXYWH(100, 100, 600, 600);
245 
246  DlPaint paint;
247  paint.setColor(DlColor::kMidGrey());
248  builder.DrawRect(dest_rect, paint);
249 
250  builder.DrawImageRect(image, source_rect, dest_rect,
251  DlImageSampling::kNearestNeighbor);
252  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
253 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [165/497]

impeller::testing::TEST_P ( AiksTest  ,
DrawLinesRenderCorrectly   
)

Definition at line 307 of file aiks_dl_path_unittests.cc.

307  {
308  DisplayListBuilder builder;
309  builder.Scale(GetContentScale().x, GetContentScale().y);
310 
311  DlPaint paint;
312  paint.setColor(DlColor::kBlue());
313  paint.setStrokeWidth(10);
314 
315  auto draw = [&builder](DlPaint& paint) {
316  for (auto cap :
317  {DlStrokeCap::kButt, DlStrokeCap::kSquare, DlStrokeCap::kRound}) {
318  paint.setStrokeCap(cap);
319  SkPoint origin = {100, 100};
320  builder.DrawLine(SkPoint{150, 100}, SkPoint{250, 100}, paint);
321  for (int d = 15; d < 90; d += 15) {
322  Matrix m = Matrix::MakeRotationZ(Degrees(d));
323  Point origin = {100, 100};
324  Point p0 = {50, 0};
325  Point p1 = {150, 0};
326  auto a = origin + m * p0;
327  auto b = origin + m * p1;
328 
329  builder.DrawLine(SkPoint::Make(a.x, a.y), SkPoint::Make(b.x, b.y),
330  paint);
331  }
332  builder.DrawLine(SkPoint{100, 150}, SkPoint{100, 250}, paint);
333  builder.DrawCircle({origin}, 35, paint);
334 
335  builder.DrawLine(SkPoint{250, 250}, SkPoint{250, 250}, paint);
336 
337  builder.Translate(250, 0);
338  }
339  builder.Translate(-750, 250);
340  };
341 
342  std::vector<DlColor> colors = {
343  DlColor::ARGB(1, 0x1f / 255.0, 0.0, 0x5c / 255.0),
344  DlColor::ARGB(1, 0x5b / 255.0, 0.0, 0x60 / 255.0),
345  DlColor::ARGB(1, 0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0),
346  DlColor::ARGB(1, 0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0),
347  DlColor::ARGB(1, 0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0),
348  DlColor::ARGB(1, 0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0),
349  DlColor::ARGB(1, 0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0)};
350  std::vector<Scalar> stops = {
351  0.0,
352  (1.0 / 6.0) * 1,
353  (1.0 / 6.0) * 2,
354  (1.0 / 6.0) * 3,
355  (1.0 / 6.0) * 4,
356  (1.0 / 6.0) * 5,
357  1.0,
358  };
359 
360  auto texture = DlImageImpeller::Make(
361  CreateTextureForFixture("airplane.jpg",
362  /*enable_mipmapping=*/true));
363 
364  draw(paint);
365 
366  paint.setColorSource(DlColorSource::MakeRadial({100, 100}, 200, stops.size(),
367  colors.data(), stops.data(),
368  DlTileMode::kMirror));
369  draw(paint);
370 
371  DlMatrix matrix = DlMatrix::MakeTranslation({-150, 75});
372  paint.setColorSource(DlColorSource::MakeImage(
373  texture, DlTileMode::kRepeat, DlTileMode::kRepeat,
374  DlImageSampling::kMipmapLinear, &matrix));
375  draw(paint);
376 
377  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
378 }

References impeller::saturated::b, impeller::DlImageImpeller::Make(), impeller::Matrix::MakeRotationZ(), and x.

◆ TEST_P() [166/497]

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() [167/497]

impeller::testing::TEST_P ( AiksTest  ,
DrawPaintTransformsBounds   
)

Definition at line 66 of file aiks_dl_runtime_effect_unittests.cc.

66  {
67  struct FragUniforms {
68  Size size;
69  } frag_uniforms = {.size = Size::MakeWH(400, 400)};
70  auto uniform_data = std::make_shared<std::vector<uint8_t>>();
71  uniform_data->resize(sizeof(FragUniforms));
72  memcpy(uniform_data->data(), &frag_uniforms, sizeof(FragUniforms));
73 
74  DlPaint paint;
75  paint.setColorSource(
76  MakeRuntimeEffect(this, "gradient.frag.iplr", uniform_data));
77 
78  DisplayListBuilder builder;
79  builder.Save();
80  builder.Scale(GetContentScale().x, GetContentScale().y);
81  builder.DrawPaint(paint);
82  builder.Restore();
83 
84  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
85 }

References impeller::TSize< Scalar >::MakeWH(), and x.

◆ TEST_P() [168/497]

impeller::testing::TEST_P ( AiksTest  ,
DrawPaintWithAdvancedBlendOverFilter   
)

Definition at line 126 of file aiks_dl_blend_unittests.cc.

126  {
127  DlPaint paint;
128  paint.setColor(DlColor::kBlack());
129  paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kNormal, 60));
130 
131  DisplayListBuilder builder;
132  paint.setColor(DlColor::kWhite());
133  builder.DrawPaint(paint);
134  paint.setColor(DlColor::kBlack());
135  builder.DrawCircle(SkPoint{300, 300}, 200, paint);
136  paint.setColor(DlColor::kGreen());
137  paint.setBlendMode(DlBlendMode::kScreen);
138  builder.DrawPaint(paint);
139 
140  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
141 }

◆ TEST_P() [169/497]

impeller::testing::TEST_P ( AiksTest  ,
DrawRectStrokesRenderCorrectly   
)

Definition at line 380 of file aiks_dl_path_unittests.cc.

380  {
381  DisplayListBuilder builder;
382  DlPaint paint;
383  paint.setColor(DlColor::kRed());
384  paint.setDrawStyle(DlDrawStyle::kStroke);
385  paint.setStrokeWidth(10);
386 
387  builder.Translate(100, 100);
388  builder.DrawPath(SkPath::Rect(SkRect::MakeSize(SkSize{100, 100})), {paint});
389 
390  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
391 }

◆ TEST_P() [170/497]

impeller::testing::TEST_P ( AiksTest  ,
DrawRectStrokesWithBevelJoinRenderCorrectly   
)

Definition at line 393 of file aiks_dl_path_unittests.cc.

393  {
394  DisplayListBuilder builder;
395  DlPaint paint;
396  paint.setColor(DlColor::kRed());
397  paint.setDrawStyle(DlDrawStyle::kStroke);
398  paint.setStrokeWidth(10);
399  paint.setStrokeJoin(DlStrokeJoin::kBevel);
400 
401  builder.Translate(100, 100);
402  builder.DrawPath(SkPath::Rect(SkRect::MakeSize(SkSize{100, 100})), paint);
403 
404  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
405 }

◆ TEST_P() [171/497]

impeller::testing::TEST_P ( AiksTest  ,
DrawScaledTextWithPerspectiveNoSaveLayer   
)

Definition at line 421 of file aiks_dl_text_unittests.cc.

421  {
422  DisplayListBuilder builder;
423 
424  Matrix matrix = Matrix(1.0, 0.0, 0.0, 0.0, //
425  0.0, 1.0, 0.0, 0.0, //
426  0.0, 0.0, 1.0, 0.01, //
427  0.0, 0.0, 0.0, 1.0) * //
428  Matrix::MakeRotationY({Degrees{10}});
429 
430  builder.Transform(SkM44::ColMajor(matrix.m));
431 
432  ASSERT_TRUE(RenderTextInCanvasSkia(GetContext(), builder, "Hello world",
433  "Roboto-Regular.ttf"));
434  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
435 }

References impeller::Matrix::m, RenderTextInCanvasSkia(), and impeller::Matrix::Transform().

◆ TEST_P() [172/497]

impeller::testing::TEST_P ( AiksTest  ,
DrawScaledTextWithPerspectiveSaveLayer   
)

Definition at line 437 of file aiks_dl_text_unittests.cc.

437  {
438  DisplayListBuilder builder;
439 
440  Matrix matrix = Matrix(1.0, 0.0, 0.0, 0.0, //
441  0.0, 1.0, 0.0, 0.0, //
442  0.0, 0.0, 1.0, 0.01, //
443  0.0, 0.0, 0.0, 1.0) * //
444  Matrix::MakeRotationY({Degrees{10}});
445 
446  DlPaint save_paint;
447  SkRect window_bounds =
448  SkRect::MakeXYWH(0, 0, GetWindowSize().width, GetWindowSize().height);
449  // Note: bounds were not needed by the AIKS version, which may indicate a bug.
450  builder.SaveLayer(&window_bounds, &save_paint);
451  builder.Transform(SkM44::ColMajor(matrix.m));
452 
453  ASSERT_TRUE(RenderTextInCanvasSkia(GetContext(), builder, "Hello world",
454  "Roboto-Regular.ttf"));
455 
456  builder.Restore();
457  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
458 }

References impeller::Matrix::m, and RenderTextInCanvasSkia().

◆ TEST_P() [173/497]

impeller::testing::TEST_P ( AiksTest  ,
DrawVerticesImageSourceWithTextureCoordinates   
)

Definition at line 270 of file aiks_dl_vertices_unittests.cc.

270  {
271  auto texture = CreateTextureForFixture("embarcadero.jpg");
272  auto dl_image = DlImageImpeller::Make(texture);
273  std::vector<DlPoint> positions = {
274  DlPoint(100, 300),
275  DlPoint(200, 100),
276  DlPoint(300, 300),
277  };
278  std::vector<DlPoint> texture_coordinates = {
279  DlPoint(0, 0),
280  DlPoint(100, 200),
281  DlPoint(200, 100),
282  };
283 
284  auto vertices = flutter::DlVertices::Make(
285  flutter::DlVertexMode::kTriangles, 3, positions.data(),
286  texture_coordinates.data(), /*colors=*/nullptr);
287 
288  flutter::DisplayListBuilder builder;
289  flutter::DlPaint paint;
290 
291  auto image_source = flutter::DlColorSource::MakeImage(
292  dl_image, flutter::DlTileMode::kRepeat, flutter::DlTileMode::kRepeat);
293 
294  paint.setColorSource(image_source);
295  builder.DrawVertices(vertices, flutter::DlBlendMode::kSrcOver, paint);
296 
297  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
298 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [174/497]

impeller::testing::TEST_P ( AiksTest  ,
DrawVerticesImageSourceWithTextureCoordinatesAndColorBlending   
)

Definition at line 300 of file aiks_dl_vertices_unittests.cc.

301  {
302  auto texture = CreateTextureForFixture("embarcadero.jpg");
303  auto dl_image = DlImageImpeller::Make(texture);
304  std::vector<DlPoint> positions = {
305  DlPoint(100, 300),
306  DlPoint(200, 100),
307  DlPoint(300, 300),
308  };
309  std::vector<flutter::DlColor> colors = {flutter::DlColor::kWhite(),
310  flutter::DlColor::kGreen(),
311  flutter::DlColor::kWhite()};
312  std::vector<DlPoint> texture_coordinates = {
313  DlPoint(0, 0),
314  DlPoint(100, 200),
315  DlPoint(200, 100),
316  };
317 
318  auto vertices = flutter::DlVertices::Make(
319  flutter::DlVertexMode::kTriangles, 3, positions.data(),
320  texture_coordinates.data(), colors.data());
321 
322  flutter::DisplayListBuilder builder;
323  flutter::DlPaint paint;
324 
325  auto image_source = flutter::DlColorSource::MakeImage(
326  dl_image, flutter::DlTileMode::kRepeat, flutter::DlTileMode::kRepeat);
327 
328  paint.setColorSource(image_source);
329  builder.DrawVertices(vertices, flutter::DlBlendMode::kModulate, paint);
330 
331  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
332 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [175/497]

impeller::testing::TEST_P ( AiksTest  ,
DrawVerticesLinearGradientWithEmptySize   
)

Definition at line 283 of file canvas_unittests.cc.

283  {
284  RenderCallback callback = [&](RenderTarget& render_target) {
285  ContentContext context(GetContext(), nullptr);
286  Canvas canvas(context, render_target, true, false);
287 
288  std::vector<flutter::DlPoint> vertex_coordinates = {
289  flutter::DlPoint(0, 0),
290  flutter::DlPoint(600, 0),
291  flutter::DlPoint(0, 600),
292  };
293  std::vector<flutter::DlPoint> texture_coordinates = {
294  flutter::DlPoint(0, 0),
295  flutter::DlPoint(500, 0),
296  flutter::DlPoint(0, 500),
297  };
298  std::vector<uint16_t> indices = {0, 1, 2};
299  flutter::DlVertices::Builder vertices_builder(
300  flutter::DlVertexMode::kTriangleStrip, vertex_coordinates.size(),
301  flutter::DlVertices::Builder::kHasTextureCoordinates, indices.size());
302  vertices_builder.store_vertices(vertex_coordinates.data());
303  vertices_builder.store_indices(indices.data());
304  vertices_builder.store_texture_coordinates(texture_coordinates.data());
305  auto vertices = vertices_builder.build();
306 
307  // The start and end points of the gradient form an empty rectangle.
308  std::vector<flutter::DlColor> colors = {flutter::DlColor::kBlue(),
309  flutter::DlColor::kRed()};
310  std::vector<Scalar> stops = {0.0, 1.0};
311  auto gradient = flutter::DlColorSource::MakeLinear(
312  {0, 0}, {0, 600}, 2, colors.data(), stops.data(),
313  flutter::DlTileMode::kClamp);
314 
315  Paint paint;
316  paint.color_source = gradient.get();
317  canvas.DrawVertices(std::make_shared<DlVerticesGeometry>(vertices, context),
318  BlendMode::kSourceOver, paint);
319 
320  canvas.EndReplay();
321  return true;
322  };
323 
324  ASSERT_TRUE(Playground::OpenPlaygroundHere(callback));
325 }

References impeller::Paint::color_source, impeller::Canvas::DrawVertices(), impeller::Canvas::EndReplay(), impeller::kSourceOver, and impeller::Playground::OpenPlaygroundHere().

◆ TEST_P() [176/497]

impeller::testing::TEST_P ( AiksTest  ,
DrawVerticesLinearGradientWithoutIndices   
)

Definition at line 209 of file aiks_dl_vertices_unittests.cc.

209  {
210  std::vector<DlPoint> positions = {
211  DlPoint(100, 300),
212  DlPoint(200, 100),
213  DlPoint(300, 300),
214  };
215 
216  auto vertices = flutter::DlVertices::Make(
217  flutter::DlVertexMode::kTriangles, 3, positions.data(),
218  /*texture_coordinates=*/nullptr, /*colors=*/nullptr);
219 
220  std::vector<flutter::DlColor> colors = {flutter::DlColor::kBlue(),
221  flutter::DlColor::kRed()};
222  const float stops[2] = {0.0, 1.0};
223 
224  auto linear = flutter::DlColorSource::MakeLinear(
225  {100.0, 100.0}, {300.0, 300.0}, 2, colors.data(), stops,
226  flutter::DlTileMode::kRepeat);
227 
228  flutter::DisplayListBuilder builder;
229  flutter::DlPaint paint;
230 
231  paint.setColorSource(linear);
232  builder.DrawVertices(vertices, flutter::DlBlendMode::kSrcOver, paint);
233 
234  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
235 }

◆ TEST_P() [177/497]

impeller::testing::TEST_P ( AiksTest  ,
DrawVerticesLinearGradientWithTextureCoordinates   
)

Definition at line 237 of file aiks_dl_vertices_unittests.cc.

237  {
238  std::vector<DlPoint> positions = {
239  DlPoint(100, 300),
240  DlPoint(200, 100),
241  DlPoint(300, 300),
242  };
243  std::vector<DlPoint> texture_coordinates = {
244  DlPoint(300, 100),
245  DlPoint(100, 200),
246  DlPoint(300, 300),
247  };
248 
249  auto vertices = flutter::DlVertices::Make(
250  flutter::DlVertexMode::kTriangles, 3, positions.data(),
251  texture_coordinates.data(), /*colors=*/nullptr);
252 
253  std::vector<flutter::DlColor> colors = {flutter::DlColor::kBlue(),
254  flutter::DlColor::kRed()};
255  const float stops[2] = {0.0, 1.0};
256 
257  auto linear = flutter::DlColorSource::MakeLinear(
258  {100.0, 100.0}, {300.0, 300.0}, 2, colors.data(), stops,
259  flutter::DlTileMode::kRepeat);
260 
261  flutter::DisplayListBuilder builder;
262  flutter::DlPaint paint;
263 
264  paint.setColorSource(linear);
265  builder.DrawVertices(vertices, flutter::DlBlendMode::kSrcOver, paint);
266 
267  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
268 }

◆ TEST_P() [178/497]

impeller::testing::TEST_P ( AiksTest  ,
DrawVerticesPremultipliesColors   
)

Definition at line 357 of file aiks_dl_vertices_unittests.cc.

357  {
358  std::vector<DlPoint> positions = {
359  DlPoint(100, 300),
360  DlPoint(200, 100),
361  DlPoint(300, 300),
362  DlPoint(200, 500),
363  };
364  auto color = flutter::DlColor::kBlue().withAlpha(0x99);
365  std::vector<uint16_t> indices = {0, 1, 2, 0, 2, 3};
366  std::vector<flutter::DlColor> colors = {color, color, color, color};
367 
368  auto vertices = flutter::DlVertices::Make(
369  flutter::DlVertexMode::kTriangles, positions.size(), positions.data(),
370  /*texture_coordinates=*/nullptr, colors.data(), indices.size(),
371  indices.data());
372 
373  flutter::DisplayListBuilder builder;
374  flutter::DlPaint paint;
375  paint.setBlendMode(flutter::DlBlendMode::kSrcOver);
376  paint.setColor(flutter::DlColor::kRed());
377 
378  builder.DrawRect(DlRect::MakeLTRB(0, 0, 400, 400), paint);
379  builder.DrawVertices(vertices, flutter::DlBlendMode::kDst, paint);
380 
381  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
382 }

◆ TEST_P() [179/497]

impeller::testing::TEST_P ( AiksTest  ,
DrawVerticesSolidColorTrianglesWithIndices   
)

Definition at line 334 of file aiks_dl_vertices_unittests.cc.

334  {
335  std::vector<DlPoint> positions = {
336  DlPoint(100, 300),
337  DlPoint(200, 100),
338  DlPoint(300, 300),
339  DlPoint(200, 500),
340  };
341  std::vector<uint16_t> indices = {0, 1, 2, 0, 2, 3};
342 
343  auto vertices = flutter::DlVertices::Make(
344  flutter::DlVertexMode::kTriangles, positions.size(), positions.data(),
345  /*texture_coordinates=*/nullptr, /*colors=*/nullptr, indices.size(),
346  indices.data());
347 
348  flutter::DisplayListBuilder builder;
349  flutter::DlPaint paint;
350 
351  paint.setColor(flutter::DlColor::kRed());
352  builder.DrawVertices(vertices, flutter::DlBlendMode::kSrcOver, paint);
353 
354  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
355 }

◆ TEST_P() [180/497]

impeller::testing::TEST_P ( AiksTest  ,
DrawVerticesSolidColorTrianglesWithoutIndices   
)

Definition at line 183 of file aiks_dl_vertices_unittests.cc.

183  {
184  // Use negative coordinates and then scale the transform by -1, -1 to make
185  // sure coverage is taking the transform into account.
186  std::vector<DlPoint> positions = {
187  DlPoint(-100, -300),
188  DlPoint(-200, -100),
189  DlPoint(-300, -300),
190  };
191  std::vector<flutter::DlColor> colors = {flutter::DlColor::kWhite(),
192  flutter::DlColor::kGreen(),
193  flutter::DlColor::kWhite()};
194 
195  auto vertices = flutter::DlVertices::Make(
196  flutter::DlVertexMode::kTriangles, 3, positions.data(),
197  /*texture_coordinates=*/nullptr, colors.data());
198 
199  flutter::DisplayListBuilder builder;
200  flutter::DlPaint paint;
201 
202  paint.setColor(flutter::DlColor::kRed().modulateOpacity(0.5));
203  builder.Scale(-1, -1);
204  builder.DrawVertices(vertices, flutter::DlBlendMode::kSrcOver, paint);
205 
206  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
207 }

◆ TEST_P() [181/497]

impeller::testing::TEST_P ( AiksTest  ,
DrawVerticesTextureCoordinatesWithFragmentShader   
)

Definition at line 416 of file aiks_dl_vertices_unittests.cc.

416  {
417  std::vector<DlPoint> positions_lt = {
418  DlPoint(0, 0), //
419  DlPoint(50, 0), //
420  DlPoint(0, 50), //
421  DlPoint(50, 50), //
422  };
423 
424  auto vertices_lt = flutter::DlVertices::Make(
425  flutter::DlVertexMode::kTriangleStrip, positions_lt.size(),
426  positions_lt.data(),
427  /*texture_coordinates=*/positions_lt.data(), /*colors=*/nullptr,
428  /*index_count=*/0,
429  /*indices=*/nullptr);
430 
431  std::vector<DlPoint> positions_rt = {
432  DlPoint(50, 0), //
433  DlPoint(100, 0), //
434  DlPoint(50, 50), //
435  DlPoint(100, 50), //
436  };
437 
438  auto vertices_rt = flutter::DlVertices::Make(
439  flutter::DlVertexMode::kTriangleStrip, positions_rt.size(),
440  positions_rt.data(),
441  /*texture_coordinates=*/positions_rt.data(), /*colors=*/nullptr,
442  /*index_count=*/0,
443  /*indices=*/nullptr);
444 
445  std::vector<DlPoint> positions_lb = {
446  DlPoint(0, 50), //
447  DlPoint(50, 50), //
448  DlPoint(0, 100), //
449  DlPoint(50, 100), //
450  };
451 
452  auto vertices_lb = flutter::DlVertices::Make(
453  flutter::DlVertexMode::kTriangleStrip, positions_lb.size(),
454  positions_lb.data(),
455  /*texture_coordinates=*/positions_lb.data(), /*colors=*/nullptr,
456  /*index_count=*/0,
457  /*indices=*/nullptr);
458 
459  std::vector<DlPoint> positions_rb = {
460  DlPoint(50, 50), //
461  DlPoint(100, 50), //
462  DlPoint(50, 100), //
463  DlPoint(100, 100), //
464  };
465 
466  auto vertices_rb = flutter::DlVertices::Make(
467  flutter::DlVertexMode::kTriangleStrip, positions_rb.size(),
468  positions_rb.data(),
469  /*texture_coordinates=*/positions_rb.data(), /*colors=*/nullptr,
470  /*index_count=*/0,
471  /*indices=*/nullptr);
472 
473  flutter::DisplayListBuilder builder;
474  flutter::DlPaint paint;
475  flutter::DlPaint rect_paint;
476  rect_paint.setColor(DlColor::kBlue());
477 
478  auto runtime_stages =
479  OpenAssetAsRuntimeStage("runtime_stage_simple.frag.iplr");
480 
481  auto runtime_stage =
482  runtime_stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
483  ASSERT_TRUE(runtime_stage);
484 
485  auto runtime_effect = DlRuntimeEffect::MakeImpeller(runtime_stage);
486  auto uniform_data = std::make_shared<std::vector<uint8_t>>();
487  auto color_source = flutter::DlColorSource::MakeRuntimeEffect(
488  runtime_effect, {}, uniform_data);
489 
490  paint.setColorSource(color_source);
491 
492  builder.Scale(GetContentScale().x, GetContentScale().y);
493  builder.Save();
494  builder.DrawRect(DlRect::MakeLTRB(0, 0, 100, 100), rect_paint);
495  builder.DrawVertices(vertices_lt, flutter::DlBlendMode::kSrcOver, paint);
496  builder.DrawVertices(vertices_rt, flutter::DlBlendMode::kSrcOver, paint);
497  builder.DrawVertices(vertices_lb, flutter::DlBlendMode::kSrcOver, paint);
498  builder.DrawVertices(vertices_rb, flutter::DlBlendMode::kSrcOver, paint);
499  builder.Restore();
500 
501  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
502 }

References impeller::PlaygroundBackendToRuntimeStageBackend(), and x.

◆ TEST_P() [182/497]

impeller::testing::TEST_P ( AiksTest  ,
DrawVerticesTextureCoordinatesWithFragmentShaderNonZeroOrigin   
)

Definition at line 506 of file aiks_dl_vertices_unittests.cc.

507  {
508  std::vector<DlPoint> positions_lt = {
509  DlPoint(200, 200), //
510  DlPoint(250, 200), //
511  DlPoint(200, 250), //
512  DlPoint(250, 250), //
513  };
514 
515  auto vertices = flutter::DlVertices::Make(
516  flutter::DlVertexMode::kTriangleStrip, positions_lt.size(),
517  positions_lt.data(),
518  /*texture_coordinates=*/positions_lt.data(), /*colors=*/nullptr,
519  /*index_count=*/0,
520  /*indices=*/nullptr);
521 
522  flutter::DisplayListBuilder builder;
523  flutter::DlPaint paint;
524  flutter::DlPaint rect_paint;
525  rect_paint.setColor(DlColor::kBlue());
526 
527  auto runtime_stages =
528  OpenAssetAsRuntimeStage("runtime_stage_position.frag.iplr");
529 
530  auto runtime_stage =
531  runtime_stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
532  ASSERT_TRUE(runtime_stage);
533 
534  auto runtime_effect = DlRuntimeEffect::MakeImpeller(runtime_stage);
535  auto rect_data = std::vector<Rect>{Rect::MakeLTRB(200, 200, 250, 250)};
536 
537  auto uniform_data = std::make_shared<std::vector<uint8_t>>();
538  uniform_data->resize(rect_data.size() * sizeof(Rect));
539  memcpy(uniform_data->data(), rect_data.data(), uniform_data->size());
540 
541  auto color_source = flutter::DlColorSource::MakeRuntimeEffect(
542  runtime_effect, {}, uniform_data);
543 
544  paint.setColorSource(color_source);
545 
546  builder.Scale(GetContentScale().x, GetContentScale().y);
547  builder.DrawRect(DlRect::MakeLTRB(200, 200, 250, 250), rect_paint);
548  builder.DrawVertices(vertices, flutter::DlBlendMode::kSrcOver, paint);
549 
550  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
551 }

References impeller::TRect< Scalar >::MakeLTRB(), impeller::PlaygroundBackendToRuntimeStageBackend(), and x.

◆ TEST_P() [183/497]

impeller::testing::TEST_P ( AiksTest  ,
DrawVerticesWithEmptyTextureCoordinates   
)

Definition at line 327 of file canvas_unittests.cc.

327  {
328  auto runtime_stages =
329  OpenAssetAsRuntimeStage("runtime_stage_simple.frag.iplr");
330 
331  auto runtime_stage =
332  runtime_stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
333  ASSERT_TRUE(runtime_stage);
334 
335  auto runtime_effect = flutter::DlRuntimeEffect::MakeImpeller(runtime_stage);
336  auto uniform_data = std::make_shared<std::vector<uint8_t>>();
337  auto color_source = flutter::DlColorSource::MakeRuntimeEffect(
338  runtime_effect, {}, uniform_data);
339 
340  RenderCallback callback = [&](RenderTarget& render_target) {
341  ContentContext context(GetContext(), nullptr);
342  Canvas canvas(context, render_target, true, false);
343 
344  std::vector<flutter::DlPoint> vertex_coordinates = {
345  flutter::DlPoint(100, 100),
346  flutter::DlPoint(300, 100),
347  flutter::DlPoint(100, 300),
348  };
349  // The bounding box of the texture coordinates is empty.
350  std::vector<flutter::DlPoint> texture_coordinates = {
351  flutter::DlPoint(0, 0),
352  flutter::DlPoint(0, 100),
353  flutter::DlPoint(0, 0),
354  };
355  std::vector<uint16_t> indices = {0, 1, 2};
356  flutter::DlVertices::Builder vertices_builder(
357  flutter::DlVertexMode::kTriangleStrip, vertex_coordinates.size(),
358  flutter::DlVertices::Builder::kHasTextureCoordinates, indices.size());
359  vertices_builder.store_vertices(vertex_coordinates.data());
360  vertices_builder.store_indices(indices.data());
361  vertices_builder.store_texture_coordinates(texture_coordinates.data());
362  auto vertices = vertices_builder.build();
363 
364  Paint paint;
365  paint.color_source = color_source.get();
366  canvas.DrawVertices(std::make_shared<DlVerticesGeometry>(vertices, context),
367  BlendMode::kSourceOver, paint);
368 
369  canvas.EndReplay();
370  return true;
371  };
372 
373  ASSERT_TRUE(Playground::OpenPlaygroundHere(callback));
374 }

References impeller::Paint::color_source, impeller::Canvas::DrawVertices(), impeller::Canvas::EndReplay(), impeller::kSourceOver, impeller::Playground::OpenPlaygroundHere(), and impeller::PlaygroundBackendToRuntimeStageBackend().

◆ TEST_P() [184/497]

impeller::testing::TEST_P ( AiksTest  ,
DrawVerticesWithInvalidIndices   
)

Definition at line 384 of file aiks_dl_vertices_unittests.cc.

384  {
385  std::vector<DlPoint> positions = {
386  DlPoint(100, 300),
387  DlPoint(200, 100),
388  DlPoint(300, 300),
389  DlPoint(200, 500),
390  };
391  std::vector<uint16_t> indices = {0, 1, 2, 0, 2, 3, 99, 100, 101};
392 
393  auto vertices = flutter::DlVertices::Make(
394  flutter::DlVertexMode::kTriangles, positions.size(), positions.data(),
395  /*texture_coordinates=*/nullptr, /*colors=*/nullptr, indices.size(),
396  indices.data());
397 
398  EXPECT_EQ(vertices->GetBounds(), DlRect::MakeLTRB(100, 100, 300, 500));
399 
400  flutter::DisplayListBuilder builder;
401  flutter::DlPaint paint;
402  paint.setBlendMode(flutter::DlBlendMode::kSrcOver);
403  paint.setColor(flutter::DlColor::kRed());
404 
405  builder.DrawRect(DlRect::MakeLTRB(0, 0, 400, 400), paint);
406  builder.DrawVertices(vertices, flutter::DlBlendMode::kSrc, paint);
407 
408  AiksContext renderer(GetContext(), nullptr);
409  std::shared_ptr<Texture> image =
410  DisplayListToTexture(builder.Build(), {1024, 768}, renderer);
411  EXPECT_TRUE(image);
412 }

References impeller::DisplayListToTexture().

◆ TEST_P() [185/497]

impeller::testing::TEST_P ( AiksTest  ,
EmptySaveLayerIgnoresPaint   
)

Definition at line 1054 of file aiks_dl_basic_unittests.cc.

1054  {
1055  DisplayListBuilder builder;
1056  builder.Scale(GetContentScale().x, GetContentScale().y);
1057 
1058  DlPaint paint;
1059  paint.setColor(DlColor::kRed());
1060  builder.DrawPaint(paint);
1061  builder.ClipRect(SkRect::MakeXYWH(100, 100, 200, 200));
1062  paint.setColor(DlColor::kBlue());
1063  builder.SaveLayer(nullptr, &paint);
1064  builder.Restore();
1065 
1066  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1067 }

References x.

◆ TEST_P() [186/497]

impeller::testing::TEST_P ( AiksTest  ,
EmptySaveLayerRendersWithClear   
)

Definition at line 1069 of file aiks_dl_basic_unittests.cc.

1069  {
1070  DisplayListBuilder builder;
1071  builder.Scale(GetContentScale().x, GetContentScale().y);
1072  auto image = DlImageImpeller::Make(CreateTextureForFixture("airplane.jpg"));
1073  builder.DrawImage(image, SkPoint{10, 10}, {});
1074  builder.ClipRect(SkRect::MakeXYWH(100, 100, 200, 200));
1075 
1076  DlPaint paint;
1077  paint.setBlendMode(DlBlendMode::kClear);
1078  builder.SaveLayer(nullptr, &paint);
1079  builder.Restore();
1080 
1081  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1082 }

References impeller::DlImageImpeller::Make(), and x.

◆ TEST_P() [187/497]

impeller::testing::TEST_P ( AiksTest  ,
FastEllipticalRRectMaskBlursRenderCorrectly   
)

Definition at line 1473 of file aiks_dl_basic_unittests.cc.

1473  {
1474  DisplayListBuilder builder;
1475 
1476  builder.Scale(GetContentScale().x, GetContentScale().y);
1477  DlPaint paint;
1478  paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kNormal, 1));
1479 
1480  DlPaint save_paint;
1481  save_paint.setColor(DlColor::kWhite());
1482  builder.DrawPaint(save_paint);
1483 
1484  paint.setColor(DlColor::kBlue());
1485  for (int i = 0; i < 5; i++) {
1486  Scalar y = i * 125;
1487  Scalar y_radius = i * 15;
1488  for (int j = 0; j < 5; j++) {
1489  Scalar x = j * 125;
1490  Scalar x_radius = j * 15;
1491  builder.DrawRRect(
1492  SkRRect::MakeRectXY(SkRect::MakeXYWH(x + 50, y + 50, 100.0f, 100.0f),
1493  x_radius, y_radius),
1494  paint);
1495  }
1496  }
1497 
1498  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1499 }

References x.

◆ TEST_P() [188/497]

impeller::testing::TEST_P ( AiksTest  ,
FastGradientTestHorizontal   
)

Definition at line 833 of file aiks_dl_gradient_unittests.cc.

833  {
834  DisplayListBuilder builder;
835  DlPaint paint;
836  builder.Translate(100.0f, 0);
837 
838  std::vector<DlColor> colors = {DlColor::kRed(), DlColor::kBlue(),
839  DlColor::kGreen()};
840  std::vector<Scalar> stops = {0.0, 0.1, 1.0};
841 
842  paint.setColorSource(DlColorSource::MakeLinear({0, 0}, {300, 0}, stops.size(),
843  colors.data(), stops.data(),
844  DlTileMode::kClamp));
845 
846  paint.setColor(DlColor::kWhite());
847  builder.DrawRect(SkRect::MakeXYWH(0, 0, 300, 300), paint);
848  builder.Translate(400, 0);
849  builder.DrawRRect(SkRRect::MakeRectXY(SkRect::MakeXYWH(0, 0, 300, 300), 4, 4),
850  paint);
851 
852  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
853 }

◆ TEST_P() [189/497]

impeller::testing::TEST_P ( AiksTest  ,
FastGradientTestHorizontalReversed   
)

Definition at line 879 of file aiks_dl_gradient_unittests.cc.

879  {
880  DisplayListBuilder builder;
881  DlPaint paint;
882  builder.Translate(100.0f, 0);
883 
884  std::vector<DlColor> colors = {DlColor::kRed(), DlColor::kBlue(),
885  DlColor::kGreen()};
886  std::vector<Scalar> stops = {0.0, 0.1, 1.0};
887 
888  paint.setColorSource(DlColorSource::MakeLinear({300, 0}, {0, 0}, stops.size(),
889  colors.data(), stops.data(),
890  DlTileMode::kClamp));
891 
892  paint.setColor(DlColor::kWhite());
893  builder.DrawRect(SkRect::MakeXYWH(0, 0, 300, 300), paint);
894  builder.Translate(400, 0);
895  builder.DrawRRect(SkRRect::MakeRectXY(SkRect::MakeXYWH(0, 0, 300, 300), 4, 4),
896  paint);
897 
898  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
899 }

◆ TEST_P() [190/497]

impeller::testing::TEST_P ( AiksTest  ,
FastGradientTestVertical   
)

Definition at line 856 of file aiks_dl_gradient_unittests.cc.

856  {
857  DisplayListBuilder builder;
858  DlPaint paint;
859  builder.Translate(100.0f, 0);
860 
861  std::vector<DlColor> colors = {DlColor::kRed(), DlColor::kBlue(),
862  DlColor::kGreen()};
863  std::vector<Scalar> stops = {0.0, 0.1, 1.0};
864 
865  paint.setColorSource(DlColorSource::MakeLinear({0, 0}, {0, 300}, stops.size(),
866  colors.data(), stops.data(),
867  DlTileMode::kClamp));
868 
869  paint.setColor(DlColor::kWhite());
870  builder.DrawRect(SkRect::MakeXYWH(0, 0, 300, 300), paint);
871  builder.Translate(400, 0);
872  builder.DrawRRect(SkRRect::MakeRectXY(SkRect::MakeXYWH(0, 0, 300, 300), 4, 4),
873  paint);
874 
875  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
876 }

◆ TEST_P() [191/497]

impeller::testing::TEST_P ( AiksTest  ,
FastGradientTestVerticalReversed   
)

Definition at line 902 of file aiks_dl_gradient_unittests.cc.

902  {
903  DisplayListBuilder builder;
904  DlPaint paint;
905  builder.Translate(100.0f, 0);
906 
907  std::vector<DlColor> colors = {DlColor::kRed(), DlColor::kBlue(),
908  DlColor::kGreen()};
909  std::vector<Scalar> stops = {0.0, 0.1, 1.0};
910 
911  paint.setColorSource(DlColorSource::MakeLinear({0, 300}, {0, 0}, stops.size(),
912  colors.data(), stops.data(),
913  DlTileMode::kClamp));
914 
915  paint.setColor(DlColor::kWhite());
916  builder.DrawRect(SkRect::MakeXYWH(0, 0, 300, 300), paint);
917  builder.Translate(400, 0);
918  builder.DrawRRect(SkRRect::MakeRectXY(SkRect::MakeXYWH(0, 0, 300, 300), 4, 4),
919  paint);
920 
921  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
922 }

◆ TEST_P() [192/497]

impeller::testing::TEST_P ( AiksTest  ,
FatStrokeArc   
)

Definition at line 464 of file aiks_dl_path_unittests.cc.

464  {
465  DlScalar stroke_width = 300;
466  DlScalar aspect = 1.0;
467  DlScalar start_angle = 0;
468  DlScalar end_angle = 90;
469  auto callback = [&]() -> sk_sp<DisplayList> {
470  if (AiksTest::ImGuiBegin("Controls", nullptr,
471  ImGuiWindowFlags_AlwaysAutoResize)) {
472  ImGui::SliderFloat("Stroke Width", &stroke_width, 1, 300);
473  ImGui::SliderFloat("Aspect", &aspect, 0.5, 2.0);
474  ImGui::SliderFloat("Start Angle", &start_angle, 0, 360);
475  ImGui::SliderFloat("End Angle", &end_angle, 0, 360);
476  ImGui::End();
477  }
478 
479  DisplayListBuilder builder;
480  DlPaint grey_paint;
481  grey_paint.setColor(DlColor(0xff111111));
482  builder.DrawPaint(grey_paint);
483 
484  DlPaint white_paint;
485  white_paint.setColor(DlColor::kWhite());
486  white_paint.setStrokeWidth(stroke_width);
487  white_paint.setDrawStyle(DlDrawStyle::kStroke);
488  DlPaint red_paint;
489  red_paint.setColor(DlColor::kRed());
490 
491  Rect rect = Rect::MakeXYWH(100, 100, 100, aspect * 100);
492  builder.DrawRect(rect, red_paint);
493  builder.DrawArc(rect, start_angle, end_angle,
494  /*useCenter=*/false, white_paint);
495  DlScalar frontier = rect.GetRight() + stroke_width / 2.0;
496  builder.DrawLine(Point(frontier, 0), Point(frontier, 150), red_paint);
497 
498  return builder.Build();
499  };
500  ASSERT_TRUE(OpenPlaygroundHere(callback));
501 }
const Scalar stroke_width

References impeller::TRect< T >::GetRight(), impeller::AiksPlayground::ImGuiBegin(), impeller::TRect< Scalar >::MakeXYWH(), and stroke_width.

◆ TEST_P() [193/497]

impeller::testing::TEST_P ( AiksTest  ,
FilledCirclesRenderCorrectly   
)

Definition at line 433 of file aiks_dl_basic_unittests.cc.

433  {
434  DisplayListBuilder builder;
435  builder.Scale(GetContentScale().x, GetContentScale().y);
436  DlPaint paint;
437  const int color_count = 3;
438  DlColor colors[color_count] = {
439  DlColor::kBlue(),
440  DlColor::kGreen(),
441  DlColor::RGBA(220.0f / 255.0f, 20.0f / 255.0f, 60.0f / 255.0f, 1.0f),
442  };
443 
444  paint.setColor(DlColor::kWhite());
445  builder.DrawPaint(paint);
446 
447  int c_index = 0;
448  int radius = 600;
449  while (radius > 0) {
450  paint.setColor(colors[(c_index++) % color_count]);
451  builder.DrawCircle(SkPoint{10, 10}, radius, paint);
452  if (radius > 30) {
453  radius -= 10;
454  } else {
455  radius -= 2;
456  }
457  }
458 
459  DlColor gradient_colors[7] = {
460  DlColor::RGBA(0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0),
461  DlColor::RGBA(0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0),
462  DlColor::RGBA(0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0),
463  DlColor::RGBA(0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0),
464  DlColor::RGBA(0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0),
465  DlColor::RGBA(0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0),
466  DlColor::RGBA(0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0),
467  };
468  DlScalar stops[7] = {
469  0.0,
470  (1.0 / 6.0) * 1,
471  (1.0 / 6.0) * 2,
472  (1.0 / 6.0) * 3,
473  (1.0 / 6.0) * 4,
474  (1.0 / 6.0) * 5,
475  1.0,
476  };
477  auto texture = CreateTextureForFixture("airplane.jpg",
478  /*enable_mipmapping=*/true);
479  auto image = DlImageImpeller::Make(texture);
480 
481  paint.setColorSource(DlColorSource::MakeRadial(
482  {500, 600}, 75, 7, gradient_colors, stops, DlTileMode::kMirror));
483  builder.DrawCircle(SkPoint{500, 600}, 100, paint);
484 
485  DlMatrix local_matrix = DlMatrix::MakeTranslation({700, 200});
486  paint.setColorSource(DlColorSource::MakeImage(
487  image, DlTileMode::kRepeat, DlTileMode::kRepeat,
488  DlImageSampling::kNearestNeighbor, &local_matrix));
489  builder.DrawCircle(SkPoint{800, 300}, 100, paint);
490 
491  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
492 }

References impeller::DlImageImpeller::Make(), and x.

◆ TEST_P() [194/497]

impeller::testing::TEST_P ( AiksTest  ,
FilledEllipsesRenderCorrectly   
)

Definition at line 560 of file aiks_dl_basic_unittests.cc.

560  {
561  DisplayListBuilder builder;
562  builder.Scale(GetContentScale().x, GetContentScale().y);
563  DlPaint paint;
564  const int color_count = 3;
565  DlColor colors[color_count] = {
566  DlColor::kBlue(),
567  DlColor::kGreen(),
568  DlColor::RGBA(220.0f / 255.0f, 20.0f / 255.0f, 60.0f / 255.0f, 1.0f),
569  };
570 
571  paint.setColor(DlColor::kWhite());
572  builder.DrawPaint(paint);
573 
574  int c_index = 0;
575  int long_radius = 600;
576  int short_radius = 600;
577  while (long_radius > 0 && short_radius > 0) {
578  paint.setColor(colors[(c_index++) % color_count]);
579  builder.DrawOval(SkRect::MakeXYWH(10 - long_radius, 10 - short_radius,
580  long_radius * 2, short_radius * 2),
581  paint);
582  builder.DrawOval(SkRect::MakeXYWH(1000 - short_radius, 750 - long_radius,
583  short_radius * 2, long_radius * 2),
584  paint);
585  if (short_radius > 30) {
586  short_radius -= 10;
587  long_radius -= 5;
588  } else {
589  short_radius -= 2;
590  long_radius -= 1;
591  }
592  }
593 
594  DlColor gradient_colors[7] = {
595  DlColor::RGBA(0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0),
596  DlColor::RGBA(0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0),
597  DlColor::RGBA(0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0),
598  DlColor::RGBA(0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0),
599  DlColor::RGBA(0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0),
600  DlColor::RGBA(0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0),
601  DlColor::RGBA(0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0),
602  };
603  DlScalar stops[7] = {
604  0.0,
605  (1.0 / 6.0) * 1,
606  (1.0 / 6.0) * 2,
607  (1.0 / 6.0) * 3,
608  (1.0 / 6.0) * 4,
609  (1.0 / 6.0) * 5,
610  1.0,
611  };
612  auto texture = CreateTextureForFixture("airplane.jpg",
613  /*enable_mipmapping=*/true);
614  auto image = DlImageImpeller::Make(texture);
615 
616  paint.setColor(DlColor::kWhite().modulateOpacity(0.5));
617 
618  paint.setColorSource(DlColorSource::MakeRadial(
619  {300, 650}, 75, 7, gradient_colors, stops, DlTileMode::kMirror));
620  builder.DrawOval(SkRect::MakeXYWH(200, 625, 200, 50), paint);
621  builder.DrawOval(SkRect::MakeXYWH(275, 550, 50, 200), paint);
622 
623  DlMatrix local_matrix = DlMatrix::MakeTranslation({610, 15});
624  paint.setColorSource(DlColorSource::MakeImage(
625  image, DlTileMode::kRepeat, DlTileMode::kRepeat,
626  DlImageSampling::kNearestNeighbor, &local_matrix));
627  builder.DrawOval(SkRect::MakeXYWH(610, 90, 200, 50), paint);
628  builder.DrawOval(SkRect::MakeXYWH(685, 15, 50, 200), paint);
629 
630  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
631 }

References impeller::DlImageImpeller::Make(), and x.

◆ TEST_P() [195/497]

impeller::testing::TEST_P ( AiksTest  ,
FilledRoundRectPathsRenderCorrectly   
)

Definition at line 1205 of file aiks_dl_basic_unittests.cc.

1205  {
1206  DisplayListBuilder builder;
1207  builder.Scale(GetContentScale().x, GetContentScale().y);
1208 
1209  DlPaint paint;
1210  const int color_count = 3;
1211  DlColor colors[color_count] = {
1212  DlColor::kBlue(),
1213  DlColor::kGreen(),
1214  DlColor::ARGB(1.0, 220.0f / 255.0f, 20.0f / 255.0f, 60.0f / 255.0f),
1215  };
1216 
1217  paint.setColor(DlColor::kWhite());
1218  builder.DrawPaint(paint);
1219 
1220  auto draw_rrect_as_path = [&builder](const SkRect& rect, Scalar x, Scalar y,
1221  const DlPaint& paint) {
1222  SkPath path;
1223  path.addRoundRect(rect, x, y);
1224  builder.DrawPath(path, paint);
1225  };
1226 
1227  int c_index = 0;
1228  for (int i = 0; i < 4; i++) {
1229  for (int j = 0; j < 4; j++) {
1230  paint.setColor(colors[(c_index++) % color_count]);
1231  draw_rrect_as_path(SkRect::MakeXYWH(i * 100 + 10, j * 100 + 20, 80, 80),
1232  i * 5 + 10, j * 5 + 10, paint);
1233  }
1234  }
1235  paint.setColor(colors[(c_index++) % color_count]);
1236  draw_rrect_as_path(SkRect::MakeXYWH(10, 420, 380, 80), 40, 40, paint);
1237  paint.setColor(colors[(c_index++) % color_count]);
1238  draw_rrect_as_path(SkRect::MakeXYWH(410, 20, 80, 380), 40, 40, paint);
1239 
1240  std::vector<DlColor> gradient_colors = {
1241  DlColor::RGBA(0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0),
1242  DlColor::RGBA(0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0),
1243  DlColor::RGBA(0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0),
1244  DlColor::RGBA(0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0),
1245  DlColor::RGBA(0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0),
1246  DlColor::RGBA(0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0),
1247  DlColor::RGBA(0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0)};
1248  std::vector<Scalar> stops = {
1249  0.0,
1250  (1.0 / 6.0) * 1,
1251  (1.0 / 6.0) * 2,
1252  (1.0 / 6.0) * 3,
1253  (1.0 / 6.0) * 4,
1254  (1.0 / 6.0) * 5,
1255  1.0,
1256  };
1257  auto texture = DlImageImpeller::Make(
1258  CreateTextureForFixture("airplane.jpg",
1259  /*enable_mipmapping=*/true));
1260 
1261  paint.setColor(DlColor::kWhite().modulateOpacity(0.1));
1262  paint.setColorSource(DlColorSource::MakeRadial(
1263  /*center=*/{550, 550},
1264  /*radius=*/75,
1265  /*stop_count=*/gradient_colors.size(),
1266  /*colors=*/gradient_colors.data(),
1267  /*stops=*/stops.data(),
1268  /*tile_mode=*/DlTileMode::kMirror));
1269  for (int i = 1; i <= 10; i++) {
1270  int j = 11 - i;
1271  draw_rrect_as_path(SkRect::MakeLTRB(550 - i * 20, 550 - j * 20, //
1272  550 + i * 20, 550 + j * 20),
1273  i * 10, j * 10, paint);
1274  }
1275  paint.setColor(DlColor::kWhite().modulateOpacity(0.5));
1276  paint.setColorSource(DlColorSource::MakeRadial(
1277  /*center=*/{200, 650},
1278  /*radius=*/75,
1279  /*stop_count=*/gradient_colors.size(),
1280  /*colors=*/gradient_colors.data(),
1281  /*stops=*/stops.data(),
1282  /*tile_mode=*/DlTileMode::kMirror));
1283  draw_rrect_as_path(SkRect::MakeLTRB(100, 610, 300, 690), 40, 40, paint);
1284  draw_rrect_as_path(SkRect::MakeLTRB(160, 550, 240, 750), 40, 40, paint);
1285 
1286  auto matrix = DlMatrix::MakeTranslation({520, 20});
1287  paint.setColor(DlColor::kWhite().modulateOpacity(0.1));
1288  paint.setColorSource(DlColorSource::MakeImage(
1289  texture, DlTileMode::kRepeat, DlTileMode::kRepeat,
1290  DlImageSampling::kMipmapLinear, &matrix));
1291  for (int i = 1; i <= 10; i++) {
1292  int j = 11 - i;
1293  draw_rrect_as_path(SkRect::MakeLTRB(720 - i * 20, 220 - j * 20, //
1294  720 + i * 20, 220 + j * 20),
1295  i * 10, j * 10, paint);
1296  }
1297  matrix = DlMatrix::MakeTranslation({800, 300});
1298  paint.setColor(DlColor::kWhite().modulateOpacity(0.5));
1299  paint.setColorSource(DlColorSource::MakeImage(
1300  texture, DlTileMode::kRepeat, DlTileMode::kRepeat,
1301  DlImageSampling::kMipmapLinear, &matrix));
1302 
1303  draw_rrect_as_path(SkRect::MakeLTRB(800, 410, 1000, 490), 40, 40, paint);
1304  draw_rrect_as_path(SkRect::MakeLTRB(860, 350, 940, 550), 40, 40, paint);
1305 
1306  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1307 }

References impeller::DlImageImpeller::Make(), and x.

◆ TEST_P() [196/497]

impeller::testing::TEST_P ( AiksTest  ,
FilledRoundRectsRenderCorrectly   
)

Definition at line 633 of file aiks_dl_basic_unittests.cc.

633  {
634  DisplayListBuilder builder;
635  builder.Scale(GetContentScale().x, GetContentScale().y);
636  DlPaint paint;
637  const int color_count = 3;
638  DlColor colors[color_count] = {
639  DlColor::kBlue(),
640  DlColor::kGreen(),
641  DlColor::RGBA(220.0f / 255.0f, 20.0f / 255.0f, 60.0f / 255.0f, 1.0f),
642  };
643 
644  paint.setColor(DlColor::kWhite());
645  builder.DrawPaint(paint);
646 
647  int c_index = 0;
648  for (int i = 0; i < 4; i++) {
649  for (int j = 0; j < 4; j++) {
650  paint.setColor(colors[(c_index++) % color_count]);
651  builder.DrawRRect(
652  SkRRect::MakeRectXY(
653  SkRect::MakeXYWH(i * 100 + 10, j * 100 + 20, 80, 80), //
654  i * 5 + 10, j * 5 + 10),
655  paint);
656  }
657  }
658  paint.setColor(colors[(c_index++) % color_count]);
659  builder.DrawRRect(
660  SkRRect::MakeRectXY(SkRect::MakeXYWH(10, 420, 380, 80), 40, 40), paint);
661  paint.setColor(colors[(c_index++) % color_count]);
662  builder.DrawRRect(
663  SkRRect::MakeRectXY(SkRect::MakeXYWH(410, 20, 80, 380), 40, 40), paint);
664 
665  DlColor gradient_colors[7] = {
666  DlColor::RGBA(0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0),
667  DlColor::RGBA(0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0),
668  DlColor::RGBA(0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0),
669  DlColor::RGBA(0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0),
670  DlColor::RGBA(0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0),
671  DlColor::RGBA(0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0),
672  DlColor::RGBA(0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0),
673  };
674  DlScalar stops[7] = {
675  0.0,
676  (1.0 / 6.0) * 1,
677  (1.0 / 6.0) * 2,
678  (1.0 / 6.0) * 3,
679  (1.0 / 6.0) * 4,
680  (1.0 / 6.0) * 5,
681  1.0,
682  };
683  auto texture = CreateTextureForFixture("airplane.jpg",
684  /*enable_mipmapping=*/true);
685  auto image = DlImageImpeller::Make(texture);
686 
687  paint.setColor(DlColor::kWhite().modulateOpacity(0.1));
688  paint.setColorSource(DlColorSource::MakeRadial(
689  {550, 550}, 75, 7, gradient_colors, stops, DlTileMode::kMirror));
690  for (int i = 1; i <= 10; i++) {
691  int j = 11 - i;
692  builder.DrawRRect(
693  SkRRect::MakeRectXY(SkRect::MakeLTRB(550 - i * 20, 550 - j * 20, //
694  550 + i * 20, 550 + j * 20),
695  i * 10, j * 10),
696  paint);
697  }
698 
699  paint.setColor(DlColor::kWhite().modulateOpacity(0.5));
700  paint.setColorSource(DlColorSource::MakeRadial(
701  {200, 650}, 75, 7, gradient_colors, stops, DlTileMode::kMirror));
702  paint.setColor(DlColor::kWhite().modulateOpacity(0.5));
703  builder.DrawRRect(
704  SkRRect::MakeRectXY(SkRect::MakeLTRB(100, 610, 300, 690), 40, 40), paint);
705  builder.DrawRRect(
706  SkRRect::MakeRectXY(SkRect::MakeLTRB(160, 550, 240, 750), 40, 40), paint);
707 
708  paint.setColor(DlColor::kWhite().modulateOpacity(0.1));
709  DlMatrix local_matrix = DlMatrix::MakeTranslation({520, 20});
710  paint.setColorSource(DlColorSource::MakeImage(
711  image, DlTileMode::kRepeat, DlTileMode::kRepeat,
712  DlImageSampling::kNearestNeighbor, &local_matrix));
713  for (int i = 1; i <= 10; i++) {
714  int j = 11 - i;
715  builder.DrawRRect(
716  SkRRect::MakeRectXY(SkRect::MakeLTRB(720 - i * 20, 220 - j * 20, //
717  720 + i * 20, 220 + j * 20),
718  i * 10, j * 10),
719  paint);
720  }
721 
722  paint.setColor(DlColor::kWhite().modulateOpacity(0.5));
723  local_matrix = DlMatrix::MakeTranslation({800, 300});
724  paint.setColorSource(DlColorSource::MakeImage(
725  image, DlTileMode::kRepeat, DlTileMode::kRepeat,
726  DlImageSampling::kNearestNeighbor, &local_matrix));
727  builder.DrawRRect(
728  SkRRect::MakeRectXY(SkRect::MakeLTRB(800, 410, 1000, 490), 40, 40),
729  paint);
730  builder.DrawRRect(
731  SkRRect::MakeRectXY(SkRect::MakeLTRB(860, 350, 940, 550), 40, 40), paint);
732 
733  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
734 }

References impeller::DlImageImpeller::Make(), and x.

◆ TEST_P() [197/497]

impeller::testing::TEST_P ( AiksTest  ,
ForegroundAdvancedBlendAppliesTransformCorrectly   
)

Definition at line 734 of file aiks_dl_blend_unittests.cc.

734  {
735  auto texture = CreateTextureForFixture("airplane.jpg",
736  /*enable_mipmapping=*/true);
737 
738  DisplayListBuilder builder;
739  builder.Rotate(30);
740 
741  DlPaint image_paint;
742  image_paint.setColorFilter(DlColorFilter::MakeBlend(
743  DlColor::RGBA(255.0f / 255.0f, 165.0f / 255.0f, 0.0f / 255.0f, 1.0f),
744  DlBlendMode::kColorDodge));
745 
746  builder.DrawImage(DlImageImpeller::Make(texture), SkPoint{200, 200},
747  DlImageSampling::kMipmapLinear, &image_paint);
748 
749  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
750 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [198/497]

impeller::testing::TEST_P ( AiksTest  ,
ForegroundBlendSubpassCollapseOptimization   
)

Definition at line 469 of file aiks_dl_blend_unittests.cc.

469  {
470  DisplayListBuilder builder;
471 
472  DlPaint save_paint;
473  save_paint.setColorFilter(
474  DlColorFilter::MakeBlend(DlColor::kRed(), DlBlendMode::kColorDodge));
475  builder.SaveLayer(nullptr, &save_paint);
476 
477  builder.Translate(500, 300);
478  builder.Rotate(120);
479 
480  DlPaint paint;
481  paint.setColor(DlColor::kBlue());
482  builder.DrawRect(SkRect::MakeXYWH(100, 100, 200, 200), paint);
483 
484  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
485 }

◆ TEST_P() [199/497]

impeller::testing::TEST_P ( AiksTest  ,
ForegroundPipelineBlendAppliesTransformCorrectly   
)

Definition at line 716 of file aiks_dl_blend_unittests.cc.

716  {
717  auto texture = CreateTextureForFixture("airplane.jpg",
718  /*enable_mipmapping=*/true);
719 
720  DisplayListBuilder builder;
721  builder.Rotate(30);
722 
723  DlPaint image_paint;
724  image_paint.setColorFilter(DlColorFilter::MakeBlend(
725  DlColor::RGBA(255.0f / 255.0f, 165.0f / 255.0f, 0.0f / 255.0f, 1.0f),
726  DlBlendMode::kSrcIn));
727 
728  builder.DrawImage(DlImageImpeller::Make(texture), SkPoint{200, 200},
729  DlImageSampling::kMipmapLinear, &image_paint);
730 
731  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
732 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [200/497]

impeller::testing::TEST_P ( AiksTest  ,
FormatSRGB   
)

Definition at line 1118 of file aiks_dl_basic_unittests.cc.

1118  {
1119  PixelFormat pixel_format =
1120  GetContext()->GetCapabilities()->GetDefaultColorFormat();
1121  EXPECT_TRUE(pixel_format == PixelFormat::kR8G8B8A8UNormInt ||
1122  pixel_format == PixelFormat::kB8G8R8A8UNormInt)
1123  << "pixel format: " << PixelFormatToString(pixel_format);
1124 }
PixelFormat
The Pixel formats supported by Impeller. The naming convention denotes the usage of the component,...
Definition: formats.h:99
constexpr const char * PixelFormatToString(PixelFormat format)
Definition: formats.h:140

References impeller::kB8G8R8A8UNormInt, impeller::kR8G8B8A8UNormInt, and impeller::PixelFormatToString().

◆ TEST_P() [201/497]

impeller::testing::TEST_P ( AiksTest  ,
FormatWideGamut   
)

Definition at line 1113 of file aiks_dl_basic_unittests.cc.

1113  {
1114  EXPECT_EQ(GetContext()->GetCapabilities()->GetDefaultColorFormat(),
1115  PixelFormat::kB10G10R10A10XR);
1116 }

References impeller::kB10G10R10A10XR.

◆ TEST_P() [202/497]

impeller::testing::TEST_P ( AiksTest  ,
FramebufferAdvancedBlendCoverage   
)

Definition at line 752 of file aiks_dl_blend_unittests.cc.

752  {
753  auto texture = CreateTextureForFixture("airplane.jpg",
754  /*enable_mipmapping=*/true);
755 
756  // Draw with an advanced blend that can use FramebufferBlendContents and
757  // verify that the scale transform is correctly applied to the image.
758  DisplayListBuilder builder;
759 
760  DlPaint paint;
761  paint.setColor(
762  DlColor::RGBA(169.0f / 255.0f, 169.0f / 255.0f, 169.0f / 255.0f, 1.0f));
763  builder.DrawPaint(paint);
764  builder.Scale(0.4, 0.4);
765 
766  DlPaint image_paint;
767  image_paint.setBlendMode(DlBlendMode::kMultiply);
768 
769  builder.DrawImage(DlImageImpeller::Make(texture), SkPoint{20, 20},
770  DlImageSampling::kMipmapLinear, &image_paint);
771 
772  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
773 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [203/497]

impeller::testing::TEST_P ( AiksTest  ,
FramebufferBlendsRespectClips   
)

If correct, this test should draw a green circle. If any red is visible, there is a depth bug.

Definition at line 122 of file aiks_dl_clip_unittests.cc.

122  {
123  DisplayListBuilder builder;
124 
125  // Clear the whole canvas with white.
126  DlPaint paint;
127  paint.setColor(DlColor::kWhite());
128  builder.DrawPaint(paint);
129 
130  builder.ClipPath(SkPath::Circle(150, 150, 50), DlCanvas::ClipOp::kIntersect);
131 
132  // Draw a red rectangle that should not show through the circle clip.
133  paint.setColor(DlColor::kRed());
134  paint.setBlendMode(DlBlendMode::kMultiply);
135  builder.DrawRect(SkRect::MakeXYWH(100, 100, 100, 100), paint);
136 
137  // Draw a green circle that shows through the clip.
138  paint.setColor(DlColor::kGreen());
139  paint.setBlendMode(DlBlendMode::kSrcOver);
140  builder.DrawCircle(SkPoint::Make(150, 150), 50, paint);
141 
142  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
143 }

◆ TEST_P() [204/497]

impeller::testing::TEST_P ( AiksTest  ,
GaussianBlurAnimatedBackdrop   
)

Definition at line 852 of file aiks_dl_blur_unittests.cc.

852  {
853  // This test is for checking out how stable rendering is when content is
854  // translated underneath a blur. Animating under a blur can cause
855  // *shimmering* to happen as a result of pixel alignment.
856  // See also: https://github.com/flutter/flutter/issues/140193
857  auto boston =
858  CreateTextureForFixture("boston.jpg", /*enable_mipmapping=*/true);
859  ASSERT_TRUE(boston);
860  int64_t count = 0;
861  Scalar sigma = 20.0;
862  Scalar freq = 0.1;
863  Scalar amp = 50.0;
864  auto callback = [&]() -> sk_sp<DisplayList> {
865  if (AiksTest::ImGuiBegin("Controls", nullptr,
866  ImGuiWindowFlags_AlwaysAutoResize)) {
867  ImGui::SliderFloat("Sigma", &sigma, 0, 200);
868  ImGui::SliderFloat("Frequency", &freq, 0.01, 2.0);
869  ImGui::SliderFloat("Amplitude", &amp, 1, 100);
870  ImGui::End();
871  }
872 
873  DisplayListBuilder builder;
874  builder.Scale(GetContentScale().x, GetContentScale().y);
875  Scalar y = amp * sin(freq * 2.0 * M_PI * count / 60);
876  builder.DrawImage(
877  DlImageImpeller::Make(boston),
878  SkPoint::Make(1024 / 2 - boston->GetSize().width / 2,
879  (768 / 2 - boston->GetSize().height / 2) + y),
880  DlImageSampling::kMipmapLinear);
881  static PlaygroundPoint point_a(Point(100, 100), 20, Color::Red());
882  static PlaygroundPoint point_b(Point(900, 700), 20, Color::Red());
883  auto [handle_a, handle_b] = DrawPlaygroundLine(point_a, point_b);
884 
885  builder.ClipRect(
886  SkRect::MakeLTRB(handle_a.x, handle_a.y, handle_b.x, handle_b.y));
887  builder.ClipRect(SkRect::MakeLTRB(100, 100, 900, 700));
888 
889  DlPaint paint;
890  paint.setBlendMode(DlBlendMode::kSrc);
891 
892  auto backdrop_filter =
893  DlImageFilter::MakeBlur(sigma, sigma, DlTileMode::kClamp);
894  builder.SaveLayer(nullptr, &paint, backdrop_filter.get());
895  count += 1;
896  return builder.Build();
897  };
898  ASSERT_TRUE(OpenPlaygroundHere(callback));
899 }

References impeller::DrawPlaygroundLine(), impeller::AiksPlayground::ImGuiBegin(), impeller::DlImageImpeller::Make(), impeller::Color::Red(), and x.

◆ TEST_P() [205/497]

impeller::testing::TEST_P ( AiksTest  ,
GaussianBlurAtPeripheryHorizontal   
)

Definition at line 823 of file aiks_dl_blur_unittests.cc.

823  {
824  DisplayListBuilder builder;
825 
826  builder.Scale(GetContentScale().x, GetContentScale().y);
827  std::shared_ptr<Texture> boston = CreateTextureForFixture("boston.jpg");
828  builder.DrawImageRect(
829  DlImageImpeller::Make(boston),
830  SkRect::MakeXYWH(0, 0, boston->GetSize().width, boston->GetSize().height),
831  SkRect::MakeLTRB(0, 0, GetWindowSize().width, 100),
832  DlImageSampling::kNearestNeighbor);
833 
834  DlPaint paint;
835  paint.setColor(DlColor::kMagenta());
836 
837  SkRRect rrect = SkRRect::MakeRectXY(
838  SkRect::MakeLTRB(0, 110, GetWindowSize().width, 210), 10, 10);
839  builder.DrawRRect(rrect, paint);
840  builder.ClipRect(SkRect::MakeLTRB(0, 50, GetWindowSize().width, 150));
841 
842  DlPaint save_paint;
843  save_paint.setBlendMode(DlBlendMode::kSrc);
844 
845  auto backdrop_filter = DlImageFilter::MakeBlur(20, 20, DlTileMode::kClamp);
846  builder.SaveLayer(nullptr, &save_paint, backdrop_filter.get());
847 
848  builder.Restore();
849  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
850 }

References impeller::DlImageImpeller::Make(), and x.

◆ TEST_P() [206/497]

impeller::testing::TEST_P ( AiksTest  ,
GaussianBlurAtPeripheryVertical   
)

Definition at line 795 of file aiks_dl_blur_unittests.cc.

795  {
796  DisplayListBuilder builder;
797 
798  DlPaint paint;
799  builder.Scale(GetContentScale().x, GetContentScale().y);
800 
801  paint.setColor(DlColor::kLimeGreen());
802  SkRRect rrect = SkRRect::MakeRectXY(
803  SkRect::MakeLTRB(0, 0, GetWindowSize().width, 100), 10, 10);
804  builder.DrawRRect(rrect, paint);
805 
806  paint.setColor(DlColor::kMagenta());
807  rrect = SkRRect::MakeRectXY(
808  SkRect::MakeLTRB(0, 110, GetWindowSize().width, 210), 10, 10);
809  builder.DrawRRect(rrect, paint);
810  builder.ClipRect(SkRect::MakeLTRB(100, 0, 200, GetWindowSize().height));
811 
812  DlPaint save_paint;
813  save_paint.setBlendMode(DlBlendMode::kSrc);
814 
815  auto backdrop_filter = DlImageFilter::MakeBlur(20, 20, DlTileMode::kClamp);
816 
817  builder.SaveLayer(nullptr, &save_paint, backdrop_filter.get());
818  builder.Restore();
819 
820  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
821 }

References x.

◆ TEST_P() [207/497]

impeller::testing::TEST_P ( AiksTest  ,
GaussianBlurBackdropTinyMipMap   
)

Definition at line 1342 of file aiks_dl_blur_unittests.cc.

1342  {
1343  AiksContext renderer(GetContext(), nullptr);
1344  for (int32_t i = 1; i < 5; ++i) {
1345  DisplayListBuilder builder;
1346 
1347  ISize clip_size = ISize(i, i);
1348  builder.Save();
1349  builder.ClipRect(
1350  SkRect::MakeXYWH(400, 400, clip_size.width, clip_size.height));
1351 
1352  DlPaint paint;
1353  paint.setColor(DlColor::kGreen());
1354  auto blur_filter = DlImageFilter::MakeBlur(0.1, 0.1, DlTileMode::kDecal);
1355  paint.setImageFilter(blur_filter);
1356 
1357  builder.DrawCircle(SkPoint{400, 400}, 200, paint);
1358  builder.Restore();
1359 
1360  auto image = DisplayListToTexture(builder.Build(), {1024, 768}, renderer);
1361  EXPECT_TRUE(image) << " length " << i;
1362  }
1363 }

References impeller::DisplayListToTexture(), impeller::TSize< T >::height, and impeller::TSize< T >::width.

◆ TEST_P() [208/497]

impeller::testing::TEST_P ( AiksTest  ,
GaussianBlurOneDimension   
)

Definition at line 1099 of file aiks_dl_blur_unittests.cc.

1099  {
1100  DisplayListBuilder builder;
1101 
1102  builder.Scale(GetContentScale().x, GetContentScale().y);
1103  builder.Scale(0.5, 0.5);
1104 
1105  std::shared_ptr<Texture> boston = CreateTextureForFixture("boston.jpg");
1106  builder.DrawImage(DlImageImpeller::Make(boston), SkPoint{100, 100}, {});
1107 
1108  DlPaint paint;
1109  paint.setBlendMode(DlBlendMode::kSrc);
1110 
1111  auto backdrop_filter = DlImageFilter::MakeBlur(50, 0, DlTileMode::kClamp);
1112  builder.SaveLayer(nullptr, &paint, backdrop_filter.get());
1113  builder.Restore();
1114  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1115 }

References impeller::DlImageImpeller::Make(), and x.

◆ TEST_P() [209/497]

impeller::testing::TEST_P ( AiksTest  ,
GaussianBlurRotatedAndClipped   
)

Definition at line 1121 of file aiks_dl_blur_unittests.cc.

1121  {
1122  DisplayListBuilder builder;
1123 
1124  std::shared_ptr<Texture> boston = CreateTextureForFixture("boston.jpg");
1125  Rect bounds =
1126  Rect::MakeXYWH(0, 0, boston->GetSize().width, boston->GetSize().height);
1127 
1128  DlPaint paint;
1129  paint.setImageFilter(DlImageFilter::MakeBlur(20, 20, DlTileMode::kDecal));
1130 
1131  Vector2 image_center = Vector2(bounds.GetSize() / 2);
1132  Vector2 clip_size = {150, 75};
1133  Vector2 center = Vector2(1024, 768) / 2;
1134  builder.Scale(GetContentScale().x, GetContentScale().y);
1135 
1136  auto clip_bounds =
1137  Rect::MakeLTRB(center.x, center.y, center.x, center.y).Expand(clip_size);
1138  builder.ClipRect(SkRect::MakeLTRB(clip_bounds.GetLeft(), clip_bounds.GetTop(),
1139  clip_bounds.GetRight(),
1140  clip_bounds.GetBottom()));
1141  builder.Translate(center.x, center.y);
1142  builder.Scale(0.6, 0.6);
1143  builder.Rotate(25);
1144 
1145  auto dst_rect = bounds.Shift(-image_center);
1146  builder.DrawImageRect(
1147  DlImageImpeller::Make(boston), /*src=*/
1148  SkRect::MakeLTRB(bounds.GetLeft(), bounds.GetTop(), bounds.GetRight(),
1149  bounds.GetBottom()),
1150  /*dst=*/
1151  SkRect::MakeLTRB(dst_rect.GetLeft(), dst_rect.GetTop(),
1152  dst_rect.GetRight(), dst_rect.GetBottom()),
1153  DlImageSampling::kMipmapLinear, &paint);
1154 
1155  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1156 }
constexpr TPoint Rotate(const Radians &angle) const
Definition: point.h:226

References impeller::TRect< T >::Expand(), impeller::TRect< T >::GetBottom(), impeller::TRect< T >::GetLeft(), impeller::TRect< T >::GetRight(), impeller::TRect< T >::GetSize(), impeller::TRect< T >::GetTop(), impeller::DlImageImpeller::Make(), impeller::TRect< Scalar >::MakeLTRB(), impeller::TRect< Scalar >::MakeXYWH(), impeller::TRect< T >::Shift(), x, impeller::TPoint< T >::x, and impeller::TPoint< T >::y.

◆ TEST_P() [210/497]

impeller::testing::TEST_P ( AiksTest  ,
GaussianBlurRotatedAndClippedInteractive   
)

Definition at line 1044 of file aiks_dl_blur_unittests.cc.

1044  {
1045  std::shared_ptr<Texture> boston = CreateTextureForFixture("boston.jpg");
1046 
1047  auto callback = [&]() -> sk_sp<DisplayList> {
1048  const char* tile_mode_names[] = {"Clamp", "Repeat", "Mirror", "Decal"};
1049  const DlTileMode tile_modes[] = {DlTileMode::kClamp, DlTileMode::kRepeat,
1050  DlTileMode::kMirror, DlTileMode::kDecal};
1051 
1052  static float rotation = 0;
1053  static float scale = 0.6;
1054  static int selected_tile_mode = 3;
1055 
1056  if (AiksTest::ImGuiBegin("Controls", nullptr,
1057  ImGuiWindowFlags_AlwaysAutoResize)) {
1058  ImGui::SliderFloat("Rotation (degrees)", &rotation, -180, 180);
1059  ImGui::SliderFloat("Scale", &scale, 0, 2.0);
1060  ImGui::Combo("Tile mode", &selected_tile_mode, tile_mode_names,
1061  sizeof(tile_mode_names) / sizeof(char*));
1062  ImGui::End();
1063  }
1064 
1065  DisplayListBuilder builder;
1066  Rect bounds =
1067  Rect::MakeXYWH(0, 0, boston->GetSize().width, boston->GetSize().height);
1068  Vector2 image_center = Vector2(bounds.GetSize() / 2);
1069  DlPaint paint;
1070  paint.setImageFilter(
1071  DlImageFilter::MakeBlur(20, 20, tile_modes[selected_tile_mode]));
1072 
1073  static PlaygroundPoint point_a(Point(362, 309), 20, Color::Red());
1074  static PlaygroundPoint point_b(Point(662, 459), 20, Color::Red());
1075  auto [handle_a, handle_b] = DrawPlaygroundLine(point_a, point_b);
1076  Vector2 center = Vector2(1024, 768) / 2;
1077 
1078  builder.Scale(GetContentScale().x, GetContentScale().y);
1079  builder.ClipRect(
1080  SkRect::MakeLTRB(handle_a.x, handle_a.y, handle_b.x, handle_b.y));
1081  builder.Translate(center.x, center.y);
1082  builder.Scale(scale, scale);
1083  builder.Rotate(rotation);
1084 
1085  SkRect sk_bounds = SkRect::MakeLTRB(bounds.GetLeft(), bounds.GetTop(),
1086  bounds.GetRight(), bounds.GetBottom());
1087  Rect dest = bounds.Shift(-image_center);
1088  SkRect sk_dst = SkRect::MakeLTRB(dest.GetLeft(), dest.GetTop(),
1089  dest.GetRight(), dest.GetBottom());
1090  builder.DrawImageRect(DlImageImpeller::Make(boston), /*src=*/sk_bounds,
1091  /*dst=*/sk_dst, DlImageSampling::kNearestNeighbor,
1092  &paint);
1093  return builder.Build();
1094  };
1095 
1096  ASSERT_TRUE(OpenPlaygroundHere(callback));
1097 }
constexpr TRect< T > Shift(T dx, T dy) const
Returns a new rectangle translated by the given offset.
Definition: rect.h:606

References impeller::DrawPlaygroundLine(), impeller::TRect< T >::GetBottom(), impeller::TRect< T >::GetLeft(), impeller::TRect< T >::GetRight(), impeller::TRect< T >::GetSize(), impeller::TRect< T >::GetTop(), impeller::AiksPlayground::ImGuiBegin(), impeller::DlImageImpeller::Make(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Color::Red(), impeller::TPoint< T >::Rotate(), scale, impeller::TRect< T >::Shift(), x, impeller::TPoint< T >::x, and impeller::TPoint< T >::y.

◆ TEST_P() [211/497]

impeller::testing::TEST_P ( AiksTest  ,
GaussianBlurRotatedNonUniform   
)

Definition at line 1158 of file aiks_dl_blur_unittests.cc.

1158  {
1159  auto callback = [&]() -> sk_sp<DisplayList> {
1160  const char* tile_mode_names[] = {"Clamp", "Repeat", "Mirror", "Decal"};
1161  const DlTileMode tile_modes[] = {DlTileMode::kClamp, DlTileMode::kRepeat,
1162  DlTileMode::kMirror, DlTileMode::kDecal};
1163 
1164  static float rotation = 45;
1165  static float scale = 0.6;
1166  static int selected_tile_mode = 3;
1167 
1168  if (AiksTest::ImGuiBegin("Controls", nullptr,
1169  ImGuiWindowFlags_AlwaysAutoResize)) {
1170  ImGui::SliderFloat("Rotation (degrees)", &rotation, -180, 180);
1171  ImGui::SliderFloat("Scale", &scale, 0, 2.0);
1172  ImGui::Combo("Tile mode", &selected_tile_mode, tile_mode_names,
1173  sizeof(tile_mode_names) / sizeof(char*));
1174  ImGui::End();
1175  }
1176 
1177  DisplayListBuilder builder;
1178 
1179  DlPaint paint;
1180  paint.setColor(DlColor::kGreen());
1181  paint.setImageFilter(
1182  DlImageFilter::MakeBlur(50, 0, tile_modes[selected_tile_mode]));
1183 
1184  Vector2 center = Vector2(1024, 768) / 2;
1185  builder.Scale(GetContentScale().x, GetContentScale().y);
1186  builder.Translate(center.x, center.y);
1187  builder.Scale(scale, scale);
1188  builder.Rotate(rotation);
1189 
1190  SkRRect rrect =
1191  SkRRect::MakeRectXY(SkRect::MakeXYWH(-100, -100, 200, 200), 10, 10);
1192  builder.DrawRRect(rrect, paint);
1193  return builder.Build();
1194  };
1195 
1196  ASSERT_TRUE(OpenPlaygroundHere(callback));
1197 }

References impeller::AiksPlayground::ImGuiBegin(), impeller::TPoint< T >::Rotate(), scale, x, impeller::TPoint< T >::x, and impeller::TPoint< T >::y.

◆ TEST_P() [212/497]

impeller::testing::TEST_P ( AiksTest  ,
GaussianBlurScaledAndClipped   
)

Definition at line 1011 of file aiks_dl_blur_unittests.cc.

1011  {
1012  DisplayListBuilder builder;
1013  std::shared_ptr<Texture> boston = CreateTextureForFixture("boston.jpg");
1014  Rect bounds =
1015  Rect::MakeXYWH(0, 0, boston->GetSize().width, boston->GetSize().height);
1016  Vector2 image_center = Vector2(bounds.GetSize() / 2);
1017 
1018  DlPaint paint;
1019  paint.setImageFilter(DlImageFilter::MakeBlur(20, 20, DlTileMode::kDecal));
1020 
1021  Vector2 clip_size = {150, 75};
1022  Vector2 center = Vector2(1024, 768) / 2;
1023  builder.Scale(GetContentScale().x, GetContentScale().y);
1024 
1025  auto rect =
1026  Rect::MakeLTRB(center.x, center.y, center.x, center.y).Expand(clip_size);
1027  builder.ClipRect(SkRect::MakeLTRB(rect.GetLeft(), rect.GetTop(),
1028  rect.GetRight(), rect.GetBottom()));
1029  builder.Translate(center.x, center.y);
1030  builder.Scale(0.6, 0.6);
1031 
1032  SkRect sk_bounds = SkRect::MakeLTRB(bounds.GetLeft(), bounds.GetTop(),
1033  bounds.GetRight(), bounds.GetBottom());
1034  Rect dest = bounds.Shift(-image_center);
1035  SkRect sk_dst = SkRect::MakeLTRB(dest.GetLeft(), dest.GetTop(),
1036  dest.GetRight(), dest.GetBottom());
1037  builder.DrawImageRect(DlImageImpeller::Make(boston), /*src=*/sk_bounds,
1038  /*dst=*/sk_dst, DlImageSampling::kNearestNeighbor,
1039  &paint);
1040 
1041  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1042 }

References impeller::TRect< T >::Expand(), impeller::TRect< T >::GetBottom(), impeller::TRect< T >::GetLeft(), impeller::TRect< T >::GetRight(), impeller::TRect< T >::GetSize(), impeller::TRect< T >::GetTop(), impeller::DlImageImpeller::Make(), impeller::TRect< Scalar >::MakeLTRB(), impeller::TRect< Scalar >::MakeXYWH(), impeller::TRect< T >::Shift(), x, impeller::TPoint< T >::x, and impeller::TPoint< T >::y.

◆ TEST_P() [213/497]

impeller::testing::TEST_P ( AiksTest  ,
GaussianBlurSolidColorTinyMipMap   
)

Definition at line 1317 of file aiks_dl_blur_unittests.cc.

1317  {
1318  AiksContext renderer(GetContext(), nullptr);
1319 
1320  for (int32_t i = 1; i < 5; ++i) {
1321  DisplayListBuilder builder;
1322  Scalar fi = i;
1323  SkPath path;
1324  path.moveTo(100, 100);
1325  path.lineTo(100 + fi, 100 + fi);
1326 
1327  DlPaint paint;
1328  paint.setColor(DlColor::kChartreuse());
1329  auto blur_filter = DlImageFilter::MakeBlur(0.1, 0.1, DlTileMode::kClamp);
1330  paint.setImageFilter(blur_filter);
1331 
1332  builder.DrawPath(path, paint);
1333 
1334  auto image = DisplayListToTexture(builder.Build(), {1024, 768}, renderer);
1335  EXPECT_TRUE(image) << " length " << i;
1336  }
1337 }

References impeller::DisplayListToTexture().

◆ TEST_P() [214/497]

impeller::testing::TEST_P ( AiksTest  ,
GaussianBlurStyleInner   
)

Definition at line 650 of file aiks_dl_blur_unittests.cc.

650  {
651  DisplayListBuilder builder;
652  builder.Scale(GetContentScale().x, GetContentScale().y);
653 
654  DlPaint paint;
655  paint.setColor(DlColor::RGBA(0.1, 0.1, 0.1, 1));
656  builder.DrawPaint(paint);
657 
658  paint.setColor(DlColor::kGreen());
659  paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kInner, 30));
660 
661  SkPath path;
662  path.moveTo(200, 200);
663  path.lineTo(300, 400);
664  path.lineTo(100, 400);
665  path.close();
666 
667  builder.DrawPath(path, paint);
668 
669  // Draw another thing to make sure the clip area is reset.
670  DlPaint red;
671  red.setColor(DlColor::kRed());
672  builder.DrawRect(SkRect::MakeXYWH(0, 0, 200, 200), red);
673 
674  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
675 }

References x.

◆ TEST_P() [215/497]

impeller::testing::TEST_P ( AiksTest  ,
GaussianBlurStyleInnerGradient   
)

Definition at line 901 of file aiks_dl_blur_unittests.cc.

901  {
902  DisplayListBuilder builder;
903 
904  builder.Scale(GetContentScale().x, GetContentScale().y);
905 
906  DlPaint paint;
907  paint.setColor(DlColor::RGBA(0.1, 0.1, 0.1, 1.0));
908  builder.DrawPaint(paint);
909 
910  std::vector<DlColor> colors = {DlColor::RGBA(0.9568, 0.2627, 0.2118, 1.0),
911  DlColor::RGBA(0.7568, 0.2627, 0.2118, 1.0)};
912  std::vector<Scalar> stops = {0.0, 1.0};
913 
914  paint = DlPaint{};
915  paint.setColorSource(DlColorSource::MakeLinear(
916  /*start_point=*/{0, 0},
917  /*end_point=*/{200, 200},
918  /*stop_count=*/colors.size(),
919  /*colors=*/colors.data(),
920  /*stops=*/stops.data(),
921  /*tile_mode=*/DlTileMode::kMirror));
922  paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kInner, 30));
923 
924  SkPath path;
925  path.moveTo(200, 200);
926  path.lineTo(300, 400);
927  path.lineTo(100, 400);
928  path.close();
929  builder.DrawPath(path, paint);
930 
931  // Draw another thing to make sure the clip area is reset.
932  DlPaint red;
933  red.setColor(DlColor::kRed());
934  builder.DrawRect(SkRect::MakeXYWH(0, 0, 200, 200), red);
935 
936  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
937 }

References x.

◆ TEST_P() [216/497]

impeller::testing::TEST_P ( AiksTest  ,
GaussianBlurStyleOuter   
)

Definition at line 677 of file aiks_dl_blur_unittests.cc.

677  {
678  DisplayListBuilder builder;
679  builder.Scale(GetContentScale().x, GetContentScale().y);
680 
681  DlPaint paint;
682  paint.setColor(DlColor::RGBA(0.1, 0.1, 0.1, 1.0));
683  builder.DrawPaint(paint);
684 
685  paint.setColor(DlColor::kGreen());
686  paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kOuter, 30));
687 
688  SkPath path;
689  path.moveTo(200, 200);
690  path.lineTo(300, 400);
691  path.lineTo(100, 400);
692  path.close();
693 
694  builder.DrawPath(path, paint);
695 
696  // Draw another thing to make sure the clip area is reset.
697  DlPaint red;
698  red.setColor(DlColor::kRed());
699  builder.DrawRect(SkRect::MakeXYWH(0, 0, 200, 200), red);
700 
701  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
702 }

References x.

◆ TEST_P() [217/497]

impeller::testing::TEST_P ( AiksTest  ,
GaussianBlurStyleOuterGradient   
)

Definition at line 975 of file aiks_dl_blur_unittests.cc.

975  {
976  DisplayListBuilder builder;
977  builder.Scale(GetContentScale().x, GetContentScale().y);
978 
979  DlPaint paint;
980  paint.setColor(DlColor::RGBA(0.1, 0.1, 0.1, 1.0));
981  builder.DrawPaint(paint);
982 
983  std::vector<DlColor> colors = {DlColor::RGBA(0.9568, 0.2627, 0.2118, 1.0),
984  DlColor::RGBA(0.7568, 0.2627, 0.2118, 1.0)};
985  std::vector<Scalar> stops = {0.0, 1.0};
986 
987  paint = DlPaint{};
988  paint.setColorSource(DlColorSource::MakeLinear(
989  /*start_point=*/{0, 0},
990  /*end_point=*/{200, 200},
991  /*stop_count=*/colors.size(),
992  /*colors=*/colors.data(),
993  /*stops=*/stops.data(),
994  /*tile_mode=*/DlTileMode::kMirror));
995  paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kOuter, 30));
996 
997  SkPath path;
998  path.moveTo(200, 200);
999  path.lineTo(300, 400);
1000  path.lineTo(100, 400);
1001  path.close();
1002  builder.DrawPath(path, paint);
1003 
1004  // Draw another thing to make sure the clip area is reset.
1005  DlPaint red;
1006  red.setColor(DlColor::kRed());
1007  builder.DrawRect(SkRect::MakeXYWH(0, 0, 200, 200), red);
1008  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1009 }

References x.

◆ TEST_P() [218/497]

impeller::testing::TEST_P ( AiksTest  ,
GaussianBlurStyleSolid   
)

Definition at line 704 of file aiks_dl_blur_unittests.cc.

704  {
705  DisplayListBuilder builder;
706  builder.Scale(GetContentScale().x, GetContentScale().y);
707 
708  DlPaint paint;
709  paint.setColor(DlColor::RGBA(0.1, 0.1, 0.1, 1.0));
710  builder.DrawPaint(paint);
711 
712  paint.setColor(DlColor::kGreen());
713  paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kSolid, 30));
714 
715  SkPath path;
716  path.moveTo(200, 200);
717  path.lineTo(300, 400);
718  path.lineTo(100, 400);
719  path.close();
720 
721  builder.DrawPath(path, paint);
722 
723  // Draw another thing to make sure the clip area is reset.
724  DlPaint red;
725  red.setColor(DlColor::kRed());
726  builder.DrawRect(SkRect::MakeXYWH(0, 0, 200, 200), red);
727 
728  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
729 }

References x.

◆ TEST_P() [219/497]

impeller::testing::TEST_P ( AiksTest  ,
GaussianBlurStyleSolidGradient   
)

Definition at line 939 of file aiks_dl_blur_unittests.cc.

939  {
940  DisplayListBuilder builder;
941  builder.Scale(GetContentScale().x, GetContentScale().y);
942 
943  DlPaint paint;
944  paint.setColor(DlColor::RGBA(0.1, 0.1, 0.1, 1.0));
945  builder.DrawPaint(paint);
946 
947  std::vector<DlColor> colors = {DlColor::RGBA(0.9568, 0.2627, 0.2118, 1.0),
948  DlColor::RGBA(0.7568, 0.2627, 0.2118, 1.0)};
949  std::vector<Scalar> stops = {0.0, 1.0};
950 
951  paint = DlPaint{};
952  paint.setColorSource(DlColorSource::MakeLinear(
953  /*start_point=*/{0, 0},
954  /*end_point=*/{200, 200},
955  /*stop_count=*/colors.size(),
956  /*colors=*/colors.data(),
957  /*stops=*/stops.data(),
958  /*tile_mode=*/DlTileMode::kMirror));
959  paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kSolid, 30));
960 
961  SkPath path;
962  path.moveTo(200, 200);
963  path.lineTo(300, 400);
964  path.lineTo(100, 400);
965  path.close();
966  builder.DrawPath(path, paint);
967 
968  // Draw another thing to make sure the clip area is reset.
969  DlPaint red;
970  red.setColor(DlColor::kRed());
971  builder.DrawRect(SkRect::MakeXYWH(0, 0, 200, 200), red);
972  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
973 }

References x.

◆ TEST_P() [220/497]

impeller::testing::TEST_P ( AiksTest  ,
GaussianBlurWithoutDecalSupport   
)

Definition at line 1263 of file aiks_dl_blur_unittests.cc.

1263  {
1264  if (GetParam() != PlaygroundBackend::kMetal) {
1265  GTEST_SKIP()
1266  << "This backend doesn't yet support setting device capabilities.";
1267  }
1268  if (!WillRenderSomething()) {
1269  // Sometimes these tests are run without playgrounds enabled which is
1270  // pointless for this test since we are asserting that
1271  // `SupportsDecalSamplerAddressMode` is called.
1272  GTEST_SKIP() << "This test requires playgrounds.";
1273  }
1274 
1275  std::shared_ptr<const Capabilities> old_capabilities =
1276  GetContext()->GetCapabilities();
1277  auto mock_capabilities = std::make_shared<MockCapabilities>();
1278  EXPECT_CALL(*mock_capabilities, SupportsDecalSamplerAddressMode())
1279  .Times(::testing::AtLeast(1))
1280  .WillRepeatedly(::testing::Return(false));
1281  FLT_FORWARD(mock_capabilities, old_capabilities, GetDefaultColorFormat);
1282  FLT_FORWARD(mock_capabilities, old_capabilities, GetDefaultStencilFormat);
1283  FLT_FORWARD(mock_capabilities, old_capabilities,
1284  GetDefaultDepthStencilFormat);
1285  FLT_FORWARD(mock_capabilities, old_capabilities, SupportsOffscreenMSAA);
1286  FLT_FORWARD(mock_capabilities, old_capabilities,
1287  SupportsImplicitResolvingMSAA);
1288  FLT_FORWARD(mock_capabilities, old_capabilities, SupportsReadFromResolve);
1289  FLT_FORWARD(mock_capabilities, old_capabilities, SupportsFramebufferFetch);
1290  FLT_FORWARD(mock_capabilities, old_capabilities, SupportsSSBO);
1291  FLT_FORWARD(mock_capabilities, old_capabilities, SupportsCompute);
1292  FLT_FORWARD(mock_capabilities, old_capabilities,
1293  SupportsTextureToTextureBlits);
1294  FLT_FORWARD(mock_capabilities, old_capabilities, GetDefaultGlyphAtlasFormat);
1295  FLT_FORWARD(mock_capabilities, old_capabilities, SupportsTriangleFan);
1296  FLT_FORWARD(mock_capabilities, old_capabilities, SupportsPrimitiveRestart);
1297  ASSERT_TRUE(SetCapabilities(mock_capabilities).ok());
1298 
1299  auto texture = DlImageImpeller::Make(CreateTextureForFixture("boston.jpg"));
1300 
1301  DisplayListBuilder builder;
1302  builder.Scale(GetContentScale().x * 0.5, GetContentScale().y * 0.5);
1303 
1304  DlPaint paint;
1305  paint.setColor(DlColor::kBlack());
1306  builder.DrawPaint(paint);
1307 
1308  auto blur_filter = DlImageFilter::MakeBlur(20, 20, DlTileMode::kDecal);
1309  paint.setImageFilter(blur_filter);
1310  builder.DrawImage(texture, SkPoint::Make(200, 200), {}, &paint);
1311  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1312 }

References impeller::kMetal, impeller::DlImageImpeller::Make(), and x.

◆ TEST_P() [221/497]

impeller::testing::TEST_P ( AiksTest  ,
GradientOvalStrokeMaskBlur   
)

Definition at line 104 of file aiks_dl_blur_unittests.cc.

104  {
105  ASSERT_TRUE(OpenPlaygroundHere(DoGradientOvalStrokeMaskBlur(
106  GetContentScale(), /*sigma=*/10, DlBlurStyle::kNormal)));
107 }
sk_sp< flutter::DisplayList > DoGradientOvalStrokeMaskBlur(Vector2 content_Scale, Scalar sigma, DlBlurStyle style)

References DoGradientOvalStrokeMaskBlur().

◆ TEST_P() [222/497]

impeller::testing::TEST_P ( AiksTest  ,
GradientOvalStrokeMaskBlurInner   
)

Definition at line 119 of file aiks_dl_blur_unittests.cc.

119  {
120  ASSERT_TRUE(OpenPlaygroundHere(DoGradientOvalStrokeMaskBlur(
121  GetContentScale(), /*sigma=*/10, DlBlurStyle::kInner)));
122 }

References DoGradientOvalStrokeMaskBlur().

◆ TEST_P() [223/497]

impeller::testing::TEST_P ( AiksTest  ,
GradientOvalStrokeMaskBlurOuter   
)

Definition at line 114 of file aiks_dl_blur_unittests.cc.

114  {
115  ASSERT_TRUE(OpenPlaygroundHere(DoGradientOvalStrokeMaskBlur(
116  GetContentScale(), /*sigma=*/10, DlBlurStyle::kOuter)));
117 }

References DoGradientOvalStrokeMaskBlur().

◆ TEST_P() [224/497]

impeller::testing::TEST_P ( AiksTest  ,
GradientOvalStrokeMaskBlurSigmaZero   
)

Definition at line 109 of file aiks_dl_blur_unittests.cc.

109  {
110  ASSERT_TRUE(OpenPlaygroundHere(DoGradientOvalStrokeMaskBlur(
111  GetContentScale(), /*sigma=*/0, DlBlurStyle::kNormal)));
112 }

References DoGradientOvalStrokeMaskBlur().

◆ TEST_P() [225/497]

impeller::testing::TEST_P ( AiksTest  ,
GradientOvalStrokeMaskBlurSolid   
)

Definition at line 124 of file aiks_dl_blur_unittests.cc.

124  {
125  ASSERT_TRUE(OpenPlaygroundHere(DoGradientOvalStrokeMaskBlur(
126  GetContentScale(), /*sigma=*/10, DlBlurStyle::kSolid)));
127 }

References DoGradientOvalStrokeMaskBlur().

◆ TEST_P() [226/497]

impeller::testing::TEST_P ( AiksTest  ,
GradientStrokesRenderCorrectly   
)

Definition at line 741 of file aiks_dl_gradient_unittests.cc.

741  {
742  // Compare with https://fiddle.skia.org/c/027392122bec8ac2b5d5de00a4b9bbe2
743  auto callback = [&]() -> sk_sp<DisplayList> {
744  static float scale = 3;
745  static bool add_circle_clip = true;
746  const char* tile_mode_names[] = {"Clamp", "Repeat", "Mirror", "Decal"};
747  const DlTileMode tile_modes[] = {DlTileMode::kClamp, DlTileMode::kRepeat,
748  DlTileMode::kMirror, DlTileMode::kDecal};
749  static int selected_tile_mode = 0;
750  static float alpha = 1;
751 
752  if (AiksTest::ImGuiBegin("Controls", nullptr,
753  ImGuiWindowFlags_AlwaysAutoResize)) {
754  ImGui::SliderFloat("Scale", &scale, 0, 6);
755  ImGui::Checkbox("Circle clip", &add_circle_clip);
756  ImGui::SliderFloat("Alpha", &alpha, 0, 1);
757  ImGui::Combo("Tile mode", &selected_tile_mode, tile_mode_names,
758  sizeof(tile_mode_names) / sizeof(char*));
759  ImGui::End();
760  }
761 
762  DisplayListBuilder builder;
763  builder.Scale(GetContentScale().x, GetContentScale().y);
764  DlPaint paint;
765  paint.setColor(DlColor::kWhite());
766  builder.DrawPaint(paint);
767 
768  paint.setDrawStyle(DlDrawStyle::kStroke);
769  paint.setColor(DlColor::kWhite().withAlpha(alpha * 255));
770  paint.setStrokeWidth(10);
771  auto tile_mode = tile_modes[selected_tile_mode];
772 
773  std::vector<DlColor> colors = {
774  DlColor(Color{0.9568, 0.2627, 0.2118, 1.0}.ToARGB()),
775  DlColor(Color{0.1294, 0.5882, 0.9529, 1.0}.ToARGB())};
776  std::vector<Scalar> stops = {0.0, 1.0};
777 
778  paint.setColorSource(DlColorSource::MakeLinear({0, 0}, {50, 50},
779  stops.size(), colors.data(),
780  stops.data(), tile_mode));
781 
782  SkPath path;
783  path.moveTo(20, 20);
784  path.quadTo({60, 20}, {60, 60});
785  path.close();
786  path.moveTo(60, 20);
787  path.quadTo({60, 60}, {20, 60});
788 
789  builder.Scale(scale, scale);
790 
791  if (add_circle_clip) {
792  static PlaygroundPoint circle_clip_point_a(Point(60, 300), 20,
793  Color::Red());
794  static PlaygroundPoint circle_clip_point_b(Point(600, 300), 20,
795  Color::Red());
796  auto [handle_a, handle_b] =
797  DrawPlaygroundLine(circle_clip_point_a, circle_clip_point_b);
798 
799  SkMatrix screen_to_canvas;
800  if (!builder.GetTransform().invert(&screen_to_canvas)) {
801  return nullptr;
802  }
803  Matrix ip_matrix = ToMatrix(screen_to_canvas);
804  Point point_a = ip_matrix * handle_a * GetContentScale();
805  Point point_b = ip_matrix * handle_b * GetContentScale();
806 
807  Point middle = (point_a + point_b) / 2;
808  auto radius = point_a.GetDistance(middle);
809  SkPath circle;
810  circle.addCircle(middle.x, middle.y, radius);
811  builder.ClipPath(circle);
812  }
813 
814  for (auto join :
815  {DlStrokeJoin::kBevel, DlStrokeJoin::kRound, DlStrokeJoin::kMiter}) {
816  paint.setStrokeJoin(join);
817  for (auto cap :
818  {DlStrokeCap::kButt, DlStrokeCap::kSquare, DlStrokeCap::kRound}) {
819  paint.setStrokeCap(cap);
820  builder.DrawPath(path, paint);
821  builder.Translate(80, 0);
822  }
823  builder.Translate(-240, 60);
824  }
825 
826  return builder.Build();
827  };
828 
829  ASSERT_TRUE(OpenPlaygroundHere(callback));
830 }
constexpr Type GetDistance(const TPoint &p) const
Definition: point.h:200

References impeller::DrawPlaygroundLine(), impeller::TPoint< T >::GetDistance(), scale, impeller::Color::ToARGB(), impeller::skia_conversions::ToMatrix(), x, impeller::TPoint< T >::x, and impeller::TPoint< T >::y.

◆ TEST_P() [227/497]

impeller::testing::TEST_P ( AiksTest  ,
ImageColorSourceEffectTransform   
)

Definition at line 900 of file aiks_dl_basic_unittests.cc.

900  {
901  // Compare with https://fiddle.skia.org/c/6cdc5aefb291fda3833b806ca347a885
902 
903  DisplayListBuilder builder;
904  auto texture = DlImageImpeller::Make(CreateTextureForFixture("monkey.png"));
905 
906  DlPaint paint;
907  paint.setColor(DlColor::kWhite());
908  builder.DrawPaint(paint);
909 
910  // Translation
911  {
912  DlMatrix matrix = DlMatrix::MakeTranslation({50, 50});
913  DlPaint paint;
914  paint.setColorSource(DlColorSource::MakeImage(
915  texture, DlTileMode::kRepeat, DlTileMode::kRepeat,
916  DlImageSampling::kNearestNeighbor, &matrix));
917 
918  builder.DrawRect(SkRect::MakeLTRB(0, 0, 100, 100), paint);
919  }
920 
921  // Rotation/skew
922  {
923  builder.Save();
924  builder.Rotate(45);
925  DlPaint paint;
926 
927  Matrix matrix(1, -1, 0, 0, //
928  1, 1, 0, 0, //
929  0, 0, 1, 0, //
930  0, 0, 0, 1);
931  paint.setColorSource(DlColorSource::MakeImage(
932  texture, DlTileMode::kRepeat, DlTileMode::kRepeat,
933  DlImageSampling::kNearestNeighbor, &matrix));
934  builder.DrawRect(SkRect::MakeLTRB(100, 0, 200, 100), paint);
935  builder.Restore();
936  }
937 
938  // Scale
939  {
940  builder.Translate(100, 0);
941  builder.Scale(100, 100);
942  DlPaint paint;
943 
944  DlMatrix matrix = DlMatrix::MakeScale({0.005, 0.005, 1});
945  paint.setColorSource(DlColorSource::MakeImage(
946  texture, DlTileMode::kRepeat, DlTileMode::kRepeat,
947  DlImageSampling::kNearestNeighbor, &matrix));
948 
949  builder.DrawRect(SkRect::MakeLTRB(0, 0, 1, 1), paint);
950  }
951 
952  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
953 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [228/497]

impeller::testing::TEST_P ( AiksTest  ,
ImageFilteredSaveLayerWithUnboundedContents   
)

Definition at line 669 of file aiks_dl_unittests.cc.

669  {
670  DisplayListBuilder builder;
671  builder.Scale(GetContentScale().x, GetContentScale().y);
672 
673  auto test = [&builder](const std::shared_ptr<DlImageFilter>& filter) {
674  auto DrawLine = [&builder](const SkPoint& p0, const SkPoint& p1,
675  const DlPaint& p) {
676  DlPaint paint = p;
677  paint.setDrawStyle(DlDrawStyle::kStroke);
678  builder.DrawPath(SkPath::Line(p0, p1), paint);
679  };
680  // Registration marks for the edge of the SaveLayer
681  DlPaint paint;
682  paint.setColor(DlColor::kWhite());
683  DrawLine(SkPoint::Make(75, 100), SkPoint::Make(225, 100), paint);
684  DrawLine(SkPoint::Make(75, 200), SkPoint::Make(225, 200), paint);
685  DrawLine(SkPoint::Make(100, 75), SkPoint::Make(100, 225), paint);
686  DrawLine(SkPoint::Make(200, 75), SkPoint::Make(200, 225), paint);
687 
688  DlPaint save_paint;
689  save_paint.setImageFilter(filter);
690  SkRect bounds = SkRect::MakeLTRB(100, 100, 200, 200);
691  builder.SaveLayer(&bounds, &save_paint);
692 
693  {
694  // DrawPaint to verify correct behavior when the contents are unbounded.
695  DlPaint paint;
696  paint.setColor(DlColor::kYellow());
697  builder.DrawPaint(paint);
698 
699  // Contrasting rectangle to see interior blurring
700  paint.setColor(DlColor::kBlue());
701  builder.DrawRect(SkRect::MakeLTRB(125, 125, 175, 175), paint);
702  }
703  builder.Restore();
704  };
705 
706  test(DlImageFilter::MakeBlur(10.0, 10.0, DlTileMode::kDecal));
707 
708  builder.Translate(200.0, 0.0);
709 
710  test(DlImageFilter::MakeDilate(10.0, 10.0));
711 
712  builder.Translate(200.0, 0.0);
713 
714  test(DlImageFilter::MakeErode(10.0, 10.0));
715 
716  builder.Translate(-400.0, 200.0);
717 
718  DlMatrix matrix = DlMatrix::MakeRotationZ(DlDegrees(10));
719 
720  auto rotate_filter =
721  DlImageFilter::MakeMatrix(matrix, DlImageSampling::kLinear);
722  test(rotate_filter);
723 
724  builder.Translate(200.0, 0.0);
725 
726  const float m[20] = {
727  0, 1, 0, 0, 0, //
728  0, 0, 1, 0, 0, //
729  1, 0, 0, 0, 0, //
730  0, 0, 0, 1, 0 //
731  };
732  auto rgb_swap_filter =
733  DlImageFilter::MakeColorFilter(DlColorFilter::MakeMatrix(m));
734  test(rgb_swap_filter);
735 
736  builder.Translate(200.0, 0.0);
737 
738  test(DlImageFilter::MakeCompose(rotate_filter, rgb_swap_filter));
739 
740  builder.Translate(-400.0, 200.0);
741 
742  test(rotate_filter->makeWithLocalMatrix(
743  DlMatrix::MakeTranslation({25.0, 25.0})));
744 
745  builder.Translate(200.0, 0.0);
746 
747  test(rgb_swap_filter->makeWithLocalMatrix(
748  DlMatrix::MakeTranslation({25.0, 25.0})));
749 
750  builder.Translate(200.0, 0.0);
751 
752  test(DlImageFilter::MakeCompose(rotate_filter, rgb_swap_filter)
753  ->makeWithLocalMatrix(DlMatrix::MakeTranslation({25.0, 25.0})));
754 
755  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
756 }

References x.

◆ TEST_P() [229/497]

impeller::testing::TEST_P ( AiksTest  ,
ImageFilteredUnboundedSaveLayerWithUnboundedContents   
)

Definition at line 233 of file aiks_dl_unittests.cc.

233  {
234  DisplayListBuilder builder(GetCullRect(GetWindowSize()));
235  builder.Scale(GetContentScale().x, GetContentScale().y);
236 
237  DlPaint save_paint;
238  save_paint.setImageFilter(
239  DlImageFilter::MakeBlur(10.0, 10.0, DlTileMode::kDecal));
240  builder.SaveLayer(nullptr, &save_paint);
241 
242  {
243  // DrawPaint to verify correct behavior when the contents are unbounded.
244  DlPaint draw_paint;
245  draw_paint.setColor(DlColor::kYellow());
246  builder.DrawPaint(draw_paint);
247 
248  // Contrasting rectangle to see interior blurring
249  DlPaint draw_rect;
250  draw_rect.setColor(DlColor::kBlue());
251  builder.DrawRect(SkRect::MakeLTRB(125, 125, 175, 175), draw_rect);
252  }
253  builder.Restore();
254 
255  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
256 }

References x.

◆ TEST_P() [230/497]

impeller::testing::TEST_P ( AiksTest  ,
LinearToSrgbFilterSubpassCollapseOptimization   
)

Definition at line 113 of file aiks_dl_unittests.cc.

113  {
114  DisplayListBuilder builder(GetCullRect(GetWindowSize()));
115 
116  DlPaint paint;
117  paint.setColorFilter(DlColorFilter::MakeLinearToSrgbGamma());
118  builder.SaveLayer(nullptr, &paint);
119 
120  builder.Translate(500, 300);
121  builder.Rotate(120); // 120 deg.
122 
123  DlPaint draw_paint;
124  draw_paint.setColor(DlColor::kBlue());
125  builder.DrawRect(SkRect::MakeXYWH(100, 100, 200, 200), draw_paint);
126 
127  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
128 }

◆ TEST_P() [231/497]

impeller::testing::TEST_P ( AiksTest  ,
MaskBlurDoesntStretchContents   
)

Definition at line 760 of file aiks_dl_blur_unittests.cc.

760  {
761  Scalar sigma = 70;
762  auto callback = [&]() -> sk_sp<DisplayList> {
763  if (AiksTest::ImGuiBegin("Controls", nullptr,
764  ImGuiWindowFlags_AlwaysAutoResize)) {
765  ImGui::SliderFloat("Sigma", &sigma, 0, 500);
766  ImGui::End();
767  }
768 
769  DisplayListBuilder builder;
770  builder.Scale(GetContentScale().x, GetContentScale().y);
771 
772  DlPaint paint;
773  paint.setColor(DlColor::RGBA(0.1, 0.1, 0.1, 1.0));
774  builder.DrawPaint(paint);
775 
776  std::shared_ptr<Texture> boston = CreateTextureForFixture("boston.jpg");
777 
778  builder.Transform(SkMatrix::Translate(100, 100) *
779  SkMatrix::Scale(0.5, 0.5));
780 
781  paint.setColorSource(DlColorSource::MakeImage(
782  DlImageImpeller::Make(boston), DlTileMode::kRepeat, DlTileMode::kRepeat,
783  DlImageSampling::kMipmapLinear));
784  paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kNormal, sigma));
785 
786  builder.DrawRect(SkRect::MakeXYWH(0, 0, boston->GetSize().width,
787  boston->GetSize().height),
788  paint);
789 
790  return builder.Build();
791  };
792  ASSERT_TRUE(OpenPlaygroundHere(callback));
793 }

References impeller::AiksPlayground::ImGuiBegin(), impeller::DlImageImpeller::Make(), and x.

◆ TEST_P() [232/497]

impeller::testing::TEST_P ( AiksTest  ,
MaskBlurOnZeroDimensionIsSkippedWideGamut   
)

Definition at line 475 of file aiks_dl_blur_unittests.cc.

475  {
476  // Making sure this test is run on a wide gamut enabled backend
477  EXPECT_EQ(GetContext()->GetCapabilities()->GetDefaultColorFormat(),
478  PixelFormat::kB10G10R10A10XR);
479 
480  DisplayListBuilder builder;
481  builder.DrawColor(DlColor::kWhite(), DlBlendMode::kSrc);
482 
483  DlPaint paint;
484  paint.setColor(DlColor::kBlue());
485  paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kNormal, 10));
486 
487  // Zero height above
488  builder.DrawRect(DlRect::MakeLTRB(100, 250, 500, 250), paint);
489  // Regular rect
490  builder.DrawRect(DlRect::MakeLTRB(100, 300, 500, 600), paint);
491  // Zero width to the right
492  builder.DrawRect(DlRect::MakeLTRB(550, 300, 550, 600), paint);
493 
494  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
495 }

References impeller::kB10G10R10A10XR.

◆ TEST_P() [233/497]

impeller::testing::TEST_P ( AiksTest  ,
MaskBlurTexture   
)

Definition at line 731 of file aiks_dl_blur_unittests.cc.

731  {
732  Scalar sigma = 30;
733  auto callback = [&]() -> sk_sp<DisplayList> {
734  if (AiksTest::ImGuiBegin("Controls", nullptr,
735  ImGuiWindowFlags_AlwaysAutoResize)) {
736  ImGui::SliderFloat("Sigma", &sigma, 0, 500);
737  ImGui::End();
738  }
739 
740  DisplayListBuilder builder;
741  builder.Scale(GetContentScale().x, GetContentScale().y);
742 
743  DlPaint paint;
744  paint.setColor(DlColor::kGreen());
745  paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kNormal, sigma));
746 
747  builder.DrawImage(
748  DlImageImpeller::Make(CreateTextureForFixture("boston.jpg")),
749  SkPoint{200, 200}, DlImageSampling::kNearestNeighbor, &paint);
750 
751  DlPaint red;
752  red.setColor(DlColor::kRed());
753  builder.DrawRect(SkRect::MakeXYWH(0, 0, 200, 200), red);
754 
755  return builder.Build();
756  };
757  ASSERT_TRUE(OpenPlaygroundHere(callback));
758 }

References impeller::AiksPlayground::ImGuiBegin(), impeller::DlImageImpeller::Make(), and x.

◆ TEST_P() [234/497]

impeller::testing::TEST_P ( AiksTest  ,
MaskBlurWithZeroSigmaIsSkipped   
)

Definition at line 462 of file aiks_dl_blur_unittests.cc.

462  {
463  DisplayListBuilder builder;
464 
465  DlPaint paint;
466  paint.setColor(DlColor::kBlue());
467  paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kNormal, 0));
468 
469  builder.DrawCircle(SkPoint{300, 300}, 200, paint);
470  builder.DrawRect(SkRect::MakeLTRB(100, 300, 500, 600), paint);
471 
472  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
473 }

◆ TEST_P() [235/497]

impeller::testing::TEST_P ( AiksTest  ,
MassiveScalingMatrixImageFilter   
)

Definition at line 1527 of file aiks_dl_basic_unittests.cc.

1527  {
1528  if (GetBackend() == PlaygroundBackend::kVulkan) {
1529  GTEST_SKIP() << "Swiftshader is running out of memory on this example.";
1530  }
1531  DisplayListBuilder builder(SkRect::MakeSize(SkSize::Make(1000, 1000)));
1532 
1533  auto filter = DlImageFilter::MakeMatrix(
1534  DlMatrix::MakeScale({0.001, 0.001, 1}), DlImageSampling::kLinear);
1535 
1536  DlPaint paint;
1537  paint.setImageFilter(filter);
1538  builder.SaveLayer(nullptr, &paint);
1539  {
1540  DlPaint paint;
1541  paint.setColor(DlColor::kRed());
1542  builder.DrawRect(SkRect::MakeLTRB(0, 0, 100000, 100000), paint);
1543  }
1544  builder.Restore();
1545 
1546  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1547 }

References impeller::kVulkan.

◆ TEST_P() [236/497]

impeller::testing::TEST_P ( AiksTest  ,
MatrixBackdropFilter   
)

Definition at line 758 of file aiks_dl_unittests.cc.

758  {
759  DisplayListBuilder builder;
760 
761  DlPaint paint;
762  paint.setColor(DlColor::kBlack());
763  builder.DrawPaint(paint);
764  builder.SaveLayer(nullptr, nullptr);
765  {
766  DlPaint paint;
767  paint.setColor(DlColor::kGreen().withAlpha(0.5 * 255));
768  paint.setBlendMode(DlBlendMode::kPlus);
769 
770  DlPaint rect_paint;
771  rect_paint.setColor(DlColor::kRed());
772  rect_paint.setStrokeWidth(4);
773  rect_paint.setDrawStyle(DlDrawStyle::kStroke);
774  builder.DrawRect(SkRect::MakeLTRB(0, 0, 300, 300), rect_paint);
775  builder.DrawCircle(SkPoint::Make(200, 200), 100, paint);
776  // Should render a second circle, centered on the bottom-right-most edge of
777  // the circle.
778  DlMatrix matrix = DlMatrix::MakeTranslation({(100 + 100 * k1OverSqrt2),
779  (100 + 100 * k1OverSqrt2)}) *
780  DlMatrix::MakeScale({0.5, 0.5, 1}) *
781  DlMatrix::MakeTranslation({-100, -100});
782  auto backdrop_filter =
783  DlImageFilter::MakeMatrix(matrix, DlImageSampling::kLinear);
784  builder.SaveLayer(nullptr, nullptr, backdrop_filter.get());
785  builder.Restore();
786  }
787  builder.Restore();
788 
789  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
790 }

References impeller::k1OverSqrt2.

◆ TEST_P() [237/497]

impeller::testing::TEST_P ( AiksTest  ,
MatrixImageFilterDoesntCullWhenScaledAndTranslatedFromOffscreen   
)

Definition at line 1005 of file aiks_dl_basic_unittests.cc.

1006  {
1007  DisplayListBuilder builder;
1008  builder.Scale(GetContentScale().x, GetContentScale().y);
1009  builder.Translate(100, 100);
1010  // Draw a circle in a SaveLayer at -300, but move it back on-screen with a
1011  // +300 translation applied by a SaveLayer image filter.
1012 
1013  DlPaint paint;
1014  paint.setImageFilter(DlImageFilter::MakeMatrix(
1015  DlMatrix::MakeTranslation({300, 0}) * DlMatrix::MakeScale({2, 2, 1}),
1016  DlImageSampling::kNearestNeighbor));
1017  builder.SaveLayer(nullptr, &paint);
1018 
1019  DlPaint circle_paint;
1020  circle_paint.setColor(DlColor::kGreen());
1021  builder.DrawCircle(SkPoint{-150, 0}, 50, circle_paint);
1022  builder.Restore();
1023 
1024  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1025 }

References x.

◆ TEST_P() [238/497]

impeller::testing::TEST_P ( AiksTest  ,
MatrixImageFilterDoesntCullWhenTranslatedFromOffscreen   
)

Definition at line 984 of file aiks_dl_basic_unittests.cc.

984  {
985  DisplayListBuilder builder;
986  builder.Scale(GetContentScale().x, GetContentScale().y);
987  builder.Translate(100, 100);
988  // Draw a circle in a SaveLayer at -300, but move it back on-screen with a
989  // +300 translation applied by a SaveLayer image filter.
990  DlPaint paint;
991  DlMatrix translate = DlMatrix::MakeTranslation({300, 0});
992  paint.setImageFilter(
993  DlImageFilter::MakeMatrix(translate, DlImageSampling::kLinear));
994  builder.SaveLayer(nullptr, &paint);
995 
996  DlPaint circle_paint;
997  circle_paint.setColor(DlColor::kGreen());
998  builder.DrawCircle(SkPoint{-300, 0}, 100, circle_paint);
999  builder.Restore();
1000 
1001  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1002 }

References x.

◆ TEST_P() [239/497]

impeller::testing::TEST_P ( AiksTest  ,
MatrixImageFilterMagnify   
)

Definition at line 637 of file aiks_dl_unittests.cc.

637  {
638  Scalar scale = 2.0;
639  auto callback = [&]() -> sk_sp<DisplayList> {
640  if (AiksTest::ImGuiBegin("Controls", nullptr,
641  ImGuiWindowFlags_AlwaysAutoResize)) {
642  ImGui::SliderFloat("Scale", &scale, 1, 2);
643  ImGui::End();
644  }
645  DisplayListBuilder builder;
646  builder.Scale(GetContentScale().x, GetContentScale().y);
647  auto image = DlImageImpeller::Make(CreateTextureForFixture("airplane.jpg"));
648 
649  builder.Translate(600, -200);
650 
651  DlMatrix matrix = DlMatrix::MakeScale({scale, scale, 1});
652  DlPaint paint;
653  paint.setImageFilter(
654  DlImageFilter::MakeMatrix(matrix, DlImageSampling::kLinear));
655  builder.SaveLayer(nullptr, &paint);
656 
657  DlPaint rect_paint;
658  rect_paint.setAlpha(0.5 * 255);
659  builder.DrawImage(image, SkPoint{0, 0}, DlImageSampling::kLinear,
660  &rect_paint);
661  builder.Restore();
662 
663  return builder.Build();
664  };
665 
666  ASSERT_TRUE(OpenPlaygroundHere(callback));
667 }

References impeller::AiksPlayground::ImGuiBegin(), impeller::DlImageImpeller::Make(), scale, and x.

◆ TEST_P() [240/497]

impeller::testing::TEST_P ( AiksTest  ,
MatrixSaveLayerFilter   
)

Definition at line 792 of file aiks_dl_unittests.cc.

792  {
793  DisplayListBuilder builder;
794 
795  DlPaint paint;
796  paint.setColor(DlColor::kBlack());
797  builder.DrawPaint(paint);
798  builder.SaveLayer(nullptr, nullptr);
799  {
800  paint.setColor(DlColor::kGreen().withAlpha(255 * 0.5));
801  paint.setBlendMode(DlBlendMode::kPlus);
802  builder.DrawCircle(SkPoint{200, 200}, 100, paint);
803  // Should render a second circle, centered on the bottom-right-most edge of
804  // the circle.
805 
806  DlMatrix matrix = DlMatrix::MakeTranslation({(200 + 100 * k1OverSqrt2),
807  (200 + 100 * k1OverSqrt2)}) *
808  DlMatrix::MakeScale({0.5, 0.5, 1}) *
809  DlMatrix::MakeTranslation({-200, -200});
810  DlPaint save_paint;
811  save_paint.setImageFilter(
812  DlImageFilter::MakeMatrix(matrix, DlImageSampling::kLinear));
813 
814  builder.SaveLayer(nullptr, &save_paint);
815 
816  DlPaint circle_paint;
817  circle_paint.setColor(DlColor::kGreen().withAlpha(255 * 0.5));
818  circle_paint.setBlendMode(DlBlendMode::kPlus);
819  builder.DrawCircle(SkPoint{200, 200}, 100, circle_paint);
820  builder.Restore();
821  }
822  builder.Restore();
823 
824  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
825 }

References impeller::k1OverSqrt2.

◆ TEST_P() [241/497]

impeller::testing::TEST_P ( AiksTest  ,
MipmapGenerationWorksCorrectly   
)

Definition at line 489 of file aiks_dl_unittests.cc.

489  {
490  TextureDescriptor texture_descriptor;
491  texture_descriptor.size = ISize{1024, 1024};
492  texture_descriptor.format = PixelFormat::kR8G8B8A8UNormInt;
493  texture_descriptor.storage_mode = StorageMode::kHostVisible;
494  texture_descriptor.mip_count = texture_descriptor.size.MipCount();
495 
496  std::vector<uint8_t> bytes(4194304);
497  bool alternate = false;
498  for (auto i = 0u; i < 4194304; i += 4) {
499  if (alternate) {
500  bytes[i] = 255;
501  bytes[i + 1] = 0;
502  bytes[i + 2] = 0;
503  bytes[i + 3] = 255;
504  } else {
505  bytes[i] = 0;
506  bytes[i + 1] = 255;
507  bytes[i + 2] = 0;
508  bytes[i + 3] = 255;
509  }
510  alternate = !alternate;
511  }
512 
513  ASSERT_EQ(texture_descriptor.GetByteSizeOfBaseMipLevel(), bytes.size());
514  auto mapping = std::make_shared<fml::NonOwnedMapping>(
515  bytes.data(), // data
516  texture_descriptor.GetByteSizeOfBaseMipLevel() // size
517  );
518  auto texture =
519  GetContext()->GetResourceAllocator()->CreateTexture(texture_descriptor);
520 
521  auto device_buffer =
522  GetContext()->GetResourceAllocator()->CreateBufferWithCopy(*mapping);
523  auto command_buffer = GetContext()->CreateCommandBuffer();
524  auto blit_pass = command_buffer->CreateBlitPass();
525 
526  blit_pass->AddCopy(DeviceBuffer::AsBufferView(std::move(device_buffer)),
527  texture);
528  blit_pass->GenerateMipmap(texture);
529  EXPECT_TRUE(blit_pass->EncodeCommands());
530  EXPECT_TRUE(GetContext()->GetCommandQueue()->Submit({command_buffer}).ok());
531 
532  auto image = DlImageImpeller::Make(texture);
533 
534  DisplayListBuilder builder;
535  builder.DrawImageRect(
536  image,
537  SkRect::MakeSize(
538  SkSize::Make(texture->GetSize().width, texture->GetSize().height)),
539  SkRect::MakeLTRB(0, 0, 100, 100), DlImageSampling::kMipmapLinear);
540 
541  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
542 }

References impeller::DeviceBuffer::AsBufferView(), impeller::TextureDescriptor::format, impeller::TextureDescriptor::GetByteSizeOfBaseMipLevel(), impeller::kHostVisible, impeller::kR8G8B8A8UNormInt, impeller::DlImageImpeller::Make(), impeller::TextureDescriptor::mip_count, impeller::TSize< T >::MipCount(), impeller::TextureDescriptor::size, and impeller::TextureDescriptor::storage_mode.

◆ TEST_P() [242/497]

impeller::testing::TEST_P ( AiksTest  ,
NoDimplesInRRectPath   
)

Definition at line 1549 of file aiks_dl_basic_unittests.cc.

1549  {
1550  Scalar width = 200.f;
1551  Scalar height = 60.f;
1552  Scalar corner = 1.f;
1553  auto callback = [&]() -> sk_sp<DisplayList> {
1554  if (AiksTest::ImGuiBegin("Controls", nullptr,
1555  ImGuiWindowFlags_AlwaysAutoResize)) {
1556  ImGui::SliderFloat("width", &width, 0, 200);
1557  ImGui::SliderFloat("height", &height, 0, 200);
1558  ImGui::SliderFloat("corner", &corner, 0, 1);
1559  ImGui::End();
1560  }
1561 
1562  DisplayListBuilder builder;
1563  builder.Scale(GetContentScale().x, GetContentScale().y);
1564 
1565  DlPaint background_paint;
1566  background_paint.setColor(DlColor(1, 0.1, 0.1, 0.1, DlColorSpace::kSRGB));
1567  builder.DrawPaint(background_paint);
1568 
1569  std::vector<DlColor> colors = {DlColor::kRed(), DlColor::kBlue()};
1570  std::vector<Scalar> stops = {0.0, 1.0};
1571 
1572  DlPaint paint;
1573  auto gradient = DlColorSource::MakeLinear(
1574  {0, 0}, {200, 200}, 2, colors.data(), stops.data(), DlTileMode::kClamp);
1575  paint.setColorSource(gradient);
1576  paint.setColor(DlColor::kWhite());
1577  paint.setDrawStyle(DlDrawStyle::kStroke);
1578  paint.setStrokeWidth(20);
1579 
1580  builder.Save();
1581  builder.Translate(100, 100);
1582 
1583  Scalar corner_x = ((1 - corner) * 50) + 50;
1584  Scalar corner_y = corner * 50 + 50;
1585  SkRRect rrect = SkRRect::MakeRectXY(SkRect::MakeXYWH(0, 0, width, height),
1586  corner_x, corner_y);
1587  builder.DrawRRect(rrect, paint);
1588  builder.Restore();
1589  return builder.Build();
1590  };
1591  ASSERT_TRUE(OpenPlaygroundHere(callback));
1592 }

References impeller::AiksPlayground::ImGuiBegin(), and x.

◆ TEST_P() [243/497]

impeller::testing::TEST_P ( AiksTest  ,
PaintBlendModeIsRespected   
)

Definition at line 173 of file aiks_dl_blend_unittests.cc.

173  {
174  DlPaint paint;
175  DisplayListBuilder builder;
176  // Default is kSourceOver.
177 
178  paint.setColor(DlColor::RGBA(1, 0, 0, 0.5));
179  builder.DrawCircle(SkPoint{150, 200}, 100, paint);
180 
181  paint.setColor(DlColor::RGBA(0, 1, 0, 0.5));
182  builder.DrawCircle(SkPoint{250, 200}, 100, paint);
183 
184  paint.setBlendMode(DlBlendMode::kPlus);
185 
186  paint.setColor(DlColor::kRed());
187  builder.DrawCircle(SkPoint{450, 250}, 100, paint);
188 
189  paint.setColor(DlColor::kGreen());
190  builder.DrawCircle(SkPoint{550, 250}, 100, paint);
191 
192  paint.setColor(DlColor::kBlue());
193  builder.DrawCircle(SkPoint{500, 150}, 100, paint);
194 
195  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
196 }

◆ TEST_P() [244/497]

impeller::testing::TEST_P ( AiksTest  ,
PipelineBlendSingleParameter   
)

Definition at line 1501 of file aiks_dl_basic_unittests.cc.

1501  {
1502  DisplayListBuilder builder;
1503 
1504  // Should render a green square in the middle of a blue circle.
1505  DlPaint paint;
1506  builder.SaveLayer(nullptr, &paint);
1507  {
1508  builder.Translate(100, 100);
1509  paint.setColor(DlColor::kBlue());
1510  builder.DrawCircle(SkPoint::Make(200, 200), 200, paint);
1511  builder.ClipRect(SkRect::MakeXYWH(100, 100, 200, 200));
1512 
1513  paint.setColor(DlColor::kGreen());
1514  paint.setBlendMode(DlBlendMode::kSrcOver);
1515  paint.setImageFilter(DlImageFilter::MakeColorFilter(
1516  DlColorFilter::MakeBlend(DlColor::kWhite(), DlBlendMode::kDst)));
1517  builder.DrawCircle(SkPoint::Make(200, 200), 200, paint);
1518  builder.Restore();
1519  }
1520 
1521  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1522 }

◆ TEST_P() [245/497]

impeller::testing::TEST_P ( AiksTest  ,
ReleasesTextureOnTeardown   
)

Definition at line 602 of file aiks_dl_unittests.cc.

602  {
603  auto context = MakeContext();
604  std::weak_ptr<Texture> weak_texture;
605 
606  {
607  auto texture = CreateTextureForFixture("table_mountain_nx.png");
608  weak_texture = texture;
609 
610  DisplayListBuilder builder;
611  builder.Scale(GetContentScale().x, GetContentScale().y);
612  builder.Translate(100.0f, 100.0f);
613 
614  DlPaint paint;
615  paint.setColorSource(DlColorSource::MakeImage(
616  DlImageImpeller::Make(texture), DlTileMode::kClamp, DlTileMode::kClamp,
617  DlImageSampling::kLinear, nullptr));
618 
619  builder.DrawRect(SkRect::MakeXYWH(0, 0, 600, 600), paint);
620 
621  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
622  }
623 
624  // See https://github.com/flutter/flutter/issues/134751.
625  //
626  // If the fence waiter was working this may not be released by the end of the
627  // scope above. Adding a manual shutdown so that future changes to the fence
628  // waiter will not flake this test.
629  context->Shutdown();
630 
631  // The texture should be released by now.
632  ASSERT_TRUE(weak_texture.expired()) << "When the texture is no longer in use "
633  "by the backend, it should be "
634  "released.";
635 }

References impeller::DlImageImpeller::Make(), and x.

◆ TEST_P() [246/497]

impeller::testing::TEST_P ( AiksTest  ,
RotateColorFilteredPath   
)

Definition at line 30 of file aiks_dl_path_unittests.cc.

30  {
31  DisplayListBuilder builder;
32  builder.Transform(SkMatrix::Translate(300, 300) * SkMatrix::RotateDeg(90));
33 
34  SkPath arrow_stem;
35  SkPath arrow_head;
36 
37  arrow_stem.moveTo({120, 190}).lineTo({120, 50});
38  arrow_head.moveTo({50, 120}).lineTo({120, 190}).lineTo({190, 120});
39 
40  auto filter =
41  DlColorFilter::MakeBlend(DlColor::kAliceBlue(), DlBlendMode::kSrcIn);
42 
43  DlPaint paint;
44  paint.setStrokeWidth(15.0);
45  paint.setStrokeCap(DlStrokeCap::kRound);
46  paint.setStrokeJoin(DlStrokeJoin::kRound);
47  paint.setDrawStyle(DlDrawStyle::kStroke);
48  paint.setColorFilter(filter);
49  paint.setColor(DlColor::kBlack());
50 
51  builder.DrawPath(arrow_stem, paint);
52  builder.DrawPath(arrow_head, paint);
53 
54  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
55 }

◆ TEST_P() [247/497]

impeller::testing::TEST_P ( AiksTest  ,
SaveLayerDrawsBehindSubsequentEntities   
)

Definition at line 1357 of file aiks_dl_basic_unittests.cc.

1357  {
1358  // Compare with https://fiddle.skia.org/c/9e03de8567ffb49e7e83f53b64bcf636
1359  DisplayListBuilder builder;
1360  DlPaint paint;
1361 
1362  paint.setColor(DlColor::kBlack());
1363  SkRect rect = SkRect::MakeXYWH(25, 25, 25, 25);
1364  builder.DrawRect(rect, paint);
1365 
1366  builder.Translate(10, 10);
1367 
1368  DlPaint save_paint;
1369  builder.SaveLayer(nullptr, &save_paint);
1370 
1371  paint.setColor(DlColor::kGreen());
1372  builder.DrawRect(rect, paint);
1373 
1374  builder.Restore();
1375 
1376  builder.Translate(10, 10);
1377  paint.setColor(DlColor::kRed());
1378  builder.DrawRect(rect, paint);
1379 
1380  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1381 }

◆ TEST_P() [248/497]

impeller::testing::TEST_P ( AiksTest  ,
SaveLayerFiltersScaleWithTransform   
)

Definition at line 1449 of file aiks_dl_basic_unittests.cc.

1449  {
1450  DisplayListBuilder builder;
1451 
1452  builder.Scale(GetContentScale().x, GetContentScale().y);
1453  builder.Translate(100, 100);
1454 
1455  auto texture = DlImageImpeller::Make(CreateTextureForFixture("boston.jpg"));
1456  auto draw_image_layer = [&builder, &texture](const DlPaint& paint) {
1457  builder.SaveLayer(nullptr, &paint);
1458  builder.DrawImage(texture, SkPoint{}, DlImageSampling::kLinear);
1459  builder.Restore();
1460  };
1461 
1462  DlPaint effect_paint;
1463  effect_paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kNormal, 6));
1464  draw_image_layer(effect_paint);
1465 
1466  builder.Translate(300, 300);
1467  builder.Scale(3, 3);
1468  draw_image_layer(effect_paint);
1469 
1470  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1471 }

References impeller::DlImageImpeller::Make(), and x.

◆ TEST_P() [249/497]

impeller::testing::TEST_P ( AiksTest  ,
SetContentsWithRegion   
)

Definition at line 568 of file aiks_dl_unittests.cc.

568  {
569  auto bridge = CreateTextureForFixture("bay_bridge.jpg");
570 
571  // Replace part of the texture with a red rectangle.
572  std::vector<uint8_t> bytes(100 * 100 * 4);
573  for (auto i = 0u; i < bytes.size(); i += 4) {
574  bytes[i] = 255;
575  bytes[i + 1] = 0;
576  bytes[i + 2] = 0;
577  bytes[i + 3] = 255;
578  }
579  auto mapping =
580  std::make_shared<fml::NonOwnedMapping>(bytes.data(), bytes.size());
581  auto device_buffer =
582  GetContext()->GetResourceAllocator()->CreateBufferWithCopy(*mapping);
583  auto cmd_buffer = GetContext()->CreateCommandBuffer();
584  auto blit_pass = cmd_buffer->CreateBlitPass();
585  blit_pass->AddCopy(DeviceBuffer::AsBufferView(device_buffer), bridge,
586  IRect::MakeLTRB(50, 50, 150, 150));
587 
588  auto did_submit =
589  blit_pass->EncodeCommands() &&
590  GetContext()->GetCommandQueue()->Submit({std::move(cmd_buffer)}).ok();
591  ASSERT_TRUE(did_submit);
592 
593  auto image = DlImageImpeller::Make(bridge);
594 
595  DisplayListBuilder builder;
596  builder.DrawImage(image, SkPoint{0, 0}, {});
597 
598  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
599 }

References impeller::DeviceBuffer::AsBufferView(), impeller::DlImageImpeller::Make(), and impeller::TRect< T >::MakeLTRB().

◆ TEST_P() [250/497]

impeller::testing::TEST_P ( AiksTest  ,
SiblingSaveLayerBoundsAreRespected   
)

Definition at line 1383 of file aiks_dl_basic_unittests.cc.

1383  {
1384  DisplayListBuilder builder;
1385  DlPaint paint;
1386  SkRect rect = SkRect::MakeXYWH(0, 0, 1000, 1000);
1387 
1388  // Black, green, and red squares offset by [10, 10].
1389  {
1390  DlPaint save_paint;
1391  SkRect bounds = SkRect::MakeXYWH(25, 25, 25, 25);
1392  builder.SaveLayer(&bounds, &save_paint);
1393  paint.setColor(DlColor::kBlack());
1394  builder.DrawRect(rect, paint);
1395  builder.Restore();
1396  }
1397 
1398  {
1399  DlPaint save_paint;
1400  SkRect bounds = SkRect::MakeXYWH(35, 35, 25, 25);
1401  builder.SaveLayer(&bounds, &save_paint);
1402  paint.setColor(DlColor::kGreen());
1403  builder.DrawRect(rect, paint);
1404  builder.Restore();
1405  }
1406 
1407  {
1408  DlPaint save_paint;
1409  SkRect bounds = SkRect::MakeXYWH(45, 45, 25, 25);
1410  builder.SaveLayer(&bounds, &save_paint);
1411  paint.setColor(DlColor::kRed());
1412  builder.DrawRect(rect, paint);
1413  builder.Restore();
1414  }
1415 
1416  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1417 }

◆ TEST_P() [251/497]

impeller::testing::TEST_P ( AiksTest  ,
SolidColorCircleMaskBlurTinySigma   
)

Definition at line 129 of file aiks_dl_blur_unittests.cc.

129  {
130  DisplayListBuilder builder;
131  builder.Scale(GetContentScale().x, GetContentScale().y);
132 
133  std::vector<float> sigmas = {0.0, 0.01, 1.0};
134  std::vector<DlColor> colors = {DlColor::kGreen(), DlColor::kYellow(),
135  DlColor::kRed()};
136  for (uint32_t i = 0; i < sigmas.size(); ++i) {
137  DlPaint paint;
138  paint.setColor(colors[i]);
139  paint.setMaskFilter(
140  DlBlurMaskFilter::Make(DlBlurStyle::kNormal, sigmas[i]));
141 
142  builder.Save();
143  builder.Translate(100 + (i * 100), 100);
144  SkRRect rrect =
145  SkRRect::MakeRectXY(SkRect::MakeXYWH(0, 0, 100.0f, 100.0f), 100, 100);
146  builder.DrawRRect(rrect, paint);
147  builder.Restore();
148  }
149 
150  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
151 }

References x.

◆ TEST_P() [252/497]

impeller::testing::TEST_P ( AiksTest  ,
SolidColorCirclesOvalsRRectsMaskBlurCorrectly   
)

Definition at line 736 of file aiks_dl_basic_unittests.cc.

736  {
737  DisplayListBuilder builder;
738  builder.Scale(GetContentScale().x, GetContentScale().y);
739  DlPaint paint;
740  paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kNormal, 1.0f));
741 
742  builder.DrawPaint(DlPaint().setColor(DlColor::kWhite()));
743 
744  paint.setColor(
745  DlColor::RGBA(220.0f / 255.0f, 20.0f / 255.0f, 60.0f / 255.0f, 1.0f));
746  Scalar y = 100.0f;
747  for (int i = 0; i < 5; i++) {
748  Scalar x = (i + 1) * 100;
749  Scalar radius = x / 10.0f;
750  builder.DrawRect(SkRect::MakeXYWH(x + 25 - radius / 2, y + radius / 2, //
751  radius, 60.0f - radius),
752  paint);
753  }
754 
755  paint.setColor(DlColor::kBlue());
756  y += 100.0f;
757  for (int i = 0; i < 5; i++) {
758  Scalar x = (i + 1) * 100;
759  Scalar radius = x / 10.0f;
760  builder.DrawCircle(SkPoint{x + 25, y + 25}, radius, paint);
761  }
762 
763  paint.setColor(DlColor::kGreen());
764  y += 100.0f;
765  for (int i = 0; i < 5; i++) {
766  Scalar x = (i + 1) * 100;
767  Scalar radius = x / 10.0f;
768  builder.DrawOval(SkRect::MakeXYWH(x + 25 - radius / 2, y + radius / 2, //
769  radius, 60.0f - radius),
770  paint);
771  }
772 
773  paint.setColor(
774  DlColor::RGBA(128.0f / 255.0f, 0.0f / 255.0f, 128.0f / 255.0f, 1.0f));
775  y += 100.0f;
776  for (int i = 0; i < 5; i++) {
777  Scalar x = (i + 1) * 100;
778  Scalar radius = x / 20.0f;
779  builder.DrawRRect(SkRRect::MakeRectXY(SkRect::MakeXYWH(x, y, 60.0f, 60.0f),
780  radius, radius),
781  paint);
782  }
783 
784  paint.setColor(
785  DlColor::RGBA(255.0f / 255.0f, 165.0f / 255.0f, 0.0f / 255.0f, 1.0f));
786  y += 100.0f;
787  for (int i = 0; i < 5; i++) {
788  Scalar x = (i + 1) * 100;
789  Scalar radius = x / 20.0f;
790  builder.DrawRRect(
791  SkRRect::MakeRectXY(SkRect::MakeXYWH(x, y, 60.0f, 60.0f), radius, 5.0f),
792  paint);
793  }
794 
795  auto dl = builder.Build();
796  ASSERT_TRUE(OpenPlaygroundHere(dl));
797 }

References x.

◆ TEST_P() [253/497]

impeller::testing::TEST_P ( AiksTest  ,
SolidColorOvalsMaskBlurTinySigma   
)

Definition at line 39 of file aiks_dl_blur_unittests.cc.

39  {
40  DisplayListBuilder builder;
41  builder.Scale(GetContentScale().x, GetContentScale().y);
42 
43  std::vector<float> sigmas = {0.0, 0.01, 1.0};
44  std::vector<DlColor> colors = {DlColor::kGreen(), DlColor::kYellow(),
45  DlColor::kRed()};
46  for (uint32_t i = 0; i < sigmas.size(); ++i) {
47  DlPaint paint;
48  paint.setColor(colors[i]);
49  paint.setMaskFilter(
50  DlBlurMaskFilter::Make(DlBlurStyle::kNormal, sigmas[i]));
51 
52  builder.Save();
53  builder.Translate(100 + (i * 100), 100);
54  SkRRect rrect =
55  SkRRect::MakeRectXY(SkRect::MakeXYWH(0, 0, 60.0f, 160.0f), 50, 100);
56  builder.DrawRRect(rrect, paint);
57  builder.Restore();
58  }
59 
60  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
61 }

References x.

◆ TEST_P() [254/497]

impeller::testing::TEST_P ( AiksTest  ,
SolidStrokesRenderCorrectly   
)

Definition at line 227 of file aiks_dl_path_unittests.cc.

227  {
228  // Compare with https://fiddle.skia.org/c/027392122bec8ac2b5d5de00a4b9bbe2
229  auto callback = [&]() -> sk_sp<DisplayList> {
230  static Color color = Color::Black().WithAlpha(0.5);
231  static float scale = 3;
232  static bool add_circle_clip = true;
233 
234  if (AiksTest::ImGuiBegin("Controls", nullptr,
235  ImGuiWindowFlags_AlwaysAutoResize)) {
236  ImGui::ColorEdit4("Color", reinterpret_cast<float*>(&color));
237  ImGui::SliderFloat("Scale", &scale, 0, 6);
238  ImGui::Checkbox("Circle clip", &add_circle_clip);
239  ImGui::End();
240  }
241 
242  DisplayListBuilder builder;
243  builder.Scale(GetContentScale().x, GetContentScale().y);
244  DlPaint paint;
245 
246  paint.setColor(DlColor::kWhite());
247  builder.DrawPaint(paint);
248 
249  paint.setColor(
250  DlColor::ARGB(color.alpha, color.red, color.green, color.blue));
251  paint.setDrawStyle(DlDrawStyle::kStroke);
252  paint.setStrokeWidth(10);
253 
254  SkPath path;
255  path.moveTo({20, 20});
256  path.quadTo({60, 20}, {60, 60});
257  path.close();
258  path.moveTo({60, 20});
259  path.quadTo({60, 60}, {20, 60});
260 
261  builder.Scale(scale, scale);
262 
263  if (add_circle_clip) {
264  static PlaygroundPoint circle_clip_point_a(Point(60, 300), 20,
265  Color::Red());
266  static PlaygroundPoint circle_clip_point_b(Point(600, 300), 20,
267  Color::Red());
268  auto [handle_a, handle_b] =
269  DrawPlaygroundLine(circle_clip_point_a, circle_clip_point_b);
270 
271  SkMatrix screen_to_canvas = SkMatrix::I();
272  if (!builder.GetTransform().invert(&screen_to_canvas)) {
273  return nullptr;
274  }
275 
276  SkPoint point_a =
277  screen_to_canvas.mapPoint(SkPoint::Make(handle_a.x, handle_a.y));
278  SkPoint point_b =
279  screen_to_canvas.mapPoint(SkPoint::Make(handle_b.x, handle_b.y));
280 
281  SkPoint middle = point_a + point_b;
282  middle.scale(GetContentScale().x / 2);
283 
284  auto radius = SkPoint::Distance(point_a, middle);
285 
286  builder.ClipPath(SkPath::Circle(middle.x(), middle.y(), radius));
287  }
288 
289  for (auto join :
290  {DlStrokeJoin::kBevel, DlStrokeJoin::kRound, DlStrokeJoin::kMiter}) {
291  paint.setStrokeJoin(join);
292  for (auto cap :
293  {DlStrokeCap::kButt, DlStrokeCap::kSquare, DlStrokeCap::kRound}) {
294  paint.setStrokeCap(cap);
295  builder.DrawPath(path, paint);
296  builder.Translate(80, 0);
297  }
298  builder.Translate(-240, 60);
299  }
300 
301  return builder.Build();
302  };
303 
304  ASSERT_TRUE(OpenPlaygroundHere(callback));
305 }

References impeller::Color::alpha, impeller::Color::Black(), impeller::Color::blue, impeller::DrawPlaygroundLine(), impeller::Color::green, impeller::AiksPlayground::ImGuiBegin(), impeller::Color::red, impeller::Color::Red(), scale, impeller::Color::WithAlpha(), and x.

◆ TEST_P() [255/497]

impeller::testing::TEST_P ( AiksTest  ,
SrgbToLinearFilterSubpassCollapseOptimization   
)

Definition at line 130 of file aiks_dl_unittests.cc.

130  {
131  DisplayListBuilder builder(GetCullRect(GetWindowSize()));
132 
133  DlPaint paint;
134  paint.setColorFilter(DlColorFilter::MakeLinearToSrgbGamma());
135  builder.SaveLayer(nullptr, &paint);
136 
137  builder.Translate(500, 300);
138  builder.Rotate(120); // 120 deg
139 
140  DlPaint draw_paint;
141  draw_paint.setColor(DlColor::kBlue());
142  builder.DrawRect(SkRect::MakeXYWH(100, 100, 200, 200), draw_paint);
143 
144  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
145 }

◆ TEST_P() [256/497]

impeller::testing::TEST_P ( AiksTest  ,
StrokedCirclesRenderCorrectly   
)

Definition at line 494 of file aiks_dl_basic_unittests.cc.

494  {
495  DisplayListBuilder builder;
496  builder.Scale(GetContentScale().x, GetContentScale().y);
497  DlPaint paint;
498  const int color_count = 3;
499  DlColor colors[color_count] = {
500  DlColor::kBlue(),
501  DlColor::kGreen(),
502  DlColor::RGBA(220.0f / 255.0f, 20.0f / 255.0f, 60.0f / 255.0f, 1.0f),
503  };
504 
505  paint.setColor(DlColor::kWhite());
506  builder.DrawPaint(paint);
507 
508  int c_index = 0;
509 
510  auto draw = [&paint, &colors, &c_index](DlCanvas& canvas, SkPoint center,
511  Scalar r, Scalar dr, int n) {
512  for (int i = 0; i < n; i++) {
513  paint.setColor(colors[(c_index++) % color_count]);
514  canvas.DrawCircle(center, r, paint);
515  r += dr;
516  }
517  };
518 
519  paint.setDrawStyle(DlDrawStyle::kStroke);
520  paint.setStrokeWidth(1);
521  draw(builder, {10, 10}, 2, 2, 14); // r = [2, 28], covers [1,29]
522  paint.setStrokeWidth(5);
523  draw(builder, {10, 10}, 35, 10, 56); // r = [35, 585], covers [30,590]
524 
525  DlColor gradient_colors[7] = {
526  DlColor::RGBA(0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0),
527  DlColor::RGBA(0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0),
528  DlColor::RGBA(0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0),
529  DlColor::RGBA(0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0),
530  DlColor::RGBA(0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0),
531  DlColor::RGBA(0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0),
532  DlColor::RGBA(0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0),
533  };
534  DlScalar stops[7] = {
535  0.0,
536  (1.0 / 6.0) * 1,
537  (1.0 / 6.0) * 2,
538  (1.0 / 6.0) * 3,
539  (1.0 / 6.0) * 4,
540  (1.0 / 6.0) * 5,
541  1.0,
542  };
543  auto texture = CreateTextureForFixture("airplane.jpg",
544  /*enable_mipmapping=*/true);
545  auto image = DlImageImpeller::Make(texture);
546 
547  paint.setColorSource(DlColorSource::MakeRadial(
548  {500, 600}, 75, 7, gradient_colors, stops, DlTileMode::kMirror));
549  draw(builder, {500, 600}, 5, 10, 10);
550 
551  DlMatrix local_matrix = DlMatrix::MakeTranslation({700, 200});
552  paint.setColorSource(DlColorSource::MakeImage(
553  image, DlTileMode::kRepeat, DlTileMode::kRepeat,
554  DlImageSampling::kNearestNeighbor, &local_matrix));
555  draw(builder, {800, 300}, 5, 10, 10);
556 
557  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
558 }

References impeller::DlImageImpeller::Make(), and x.

◆ TEST_P() [257/497]

impeller::testing::TEST_P ( AiksTest  ,
StrokedPathWithMoveToThenCloseDrawnCorrectly   
)

Definition at line 545 of file aiks_dl_unittests.cc.

545  {
546  SkPath path;
547  path.moveTo(0, 400)
548  .lineTo(0, 0)
549  .lineTo(400, 0)
550  // MoveTo implicitly adds a contour, ensure that close doesn't
551  // add another nearly-empty contour.
552  .moveTo(0, 400)
553  .close();
554 
555  DisplayListBuilder builder;
556  builder.Translate(50, 50);
557 
558  DlPaint paint;
559  paint.setColor(DlColor::kBlue());
560  paint.setStrokeCap(DlStrokeCap::kRound);
561  paint.setStrokeWidth(10);
562  paint.setDrawStyle(DlDrawStyle::kStroke);
563  builder.DrawPath(path, paint);
564 
565  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
566 }

◆ TEST_P() [258/497]

impeller::testing::TEST_P ( AiksTest  ,
SubpassWithClearColorOptimization   
)

Definition at line 955 of file aiks_dl_basic_unittests.cc.

955  {
956  DisplayListBuilder builder;
957 
958  // Use a non-srcOver blend mode to ensure that we don't detect this as an
959  // opacity peephole optimization.
960  DlPaint paint;
961  paint.setColor(DlColor::kBlue().modulateOpacity(0.5));
962  paint.setBlendMode(DlBlendMode::kSrc);
963 
964  SkRect bounds = SkRect::MakeLTRB(0, 0, 200, 200);
965  builder.SaveLayer(&bounds, &paint);
966 
967  paint.setColor(DlColor::kTransparent());
968  paint.setBlendMode(DlBlendMode::kSrc);
969  builder.DrawPaint(paint);
970  builder.Restore();
971 
972  paint.setColor(DlColor::kBlue());
973  paint.setBlendMode(DlBlendMode::kDstOver);
974  builder.SaveLayer(nullptr, &paint);
975  builder.Restore();
976 
977  // This playground should appear blank on CI since we are only drawing
978  // transparent black. If the clear color optimization is broken, the texture
979  // will be filled with NaNs and may produce a magenta texture on macOS or iOS.
980  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
981 }

◆ TEST_P() [259/497]

impeller::testing::TEST_P ( AiksTest  ,
SupportsBlitToOnscreen   
)

Definition at line 376 of file canvas_unittests.cc.

376  {
377  ContentContext context(GetContext(), nullptr);
378  auto canvas = CreateTestCanvas(context, Rect::MakeLTRB(0, 0, 100, 100),
379  /*requires_readback=*/true);
380 
381  if (GetBackend() == PlaygroundBackend::kOpenGLES) {
382  EXPECT_FALSE(canvas->SupportsBlitToOnscreen());
383  } else {
384  EXPECT_TRUE(canvas->SupportsBlitToOnscreen());
385  }
386 }

References CreateTestCanvas(), impeller::kOpenGLES, and impeller::TRect< Scalar >::MakeLTRB().

◆ TEST_P() [260/497]

impeller::testing::TEST_P ( AiksTest  ,
TextContentsMismatchedTransformTest   
)

Definition at line 621 of file aiks_dl_text_unittests.cc.

621  {
622  AiksContext aiks_context(GetContext(),
623  std::make_shared<TypographerContextSkia>());
624 
625  // Verifies that TextContents only use the scale/transform that is
626  // computed during preroll.
627  constexpr const char* font_fixture = "Roboto-Regular.ttf";
628 
629  // Construct the text blob.
630  auto c_font_fixture = std::string(font_fixture);
631  auto mapping = flutter::testing::OpenFixtureAsSkData(c_font_fixture.c_str());
632  ASSERT_TRUE(mapping);
633 
634  sk_sp<SkFontMgr> font_mgr = txt::GetDefaultFontManager();
635  SkFont sk_font(font_mgr->makeFromData(mapping), 16);
636 
637  auto blob = SkTextBlob::MakeFromString("Hello World", sk_font);
638  ASSERT_TRUE(blob);
639 
640  auto text_frame = MakeTextFrameFromTextBlobSkia(blob);
641 
642  // Simulate recording the text frame during preroll.
643  Matrix preroll_matrix =
644  Matrix::MakeTranslateScale({1.5, 1.5, 1}, {100, 50, 0});
645  Point preroll_point = Point{23, 45};
646  {
647  auto scale = TextFrame::RoundScaledFontSize(
648  (preroll_matrix * Matrix::MakeTranslation(preroll_point))
649  .GetMaxBasisLengthXY());
650 
651  aiks_context.GetContentContext().GetLazyGlyphAtlas()->AddTextFrame(
652  text_frame, //
653  scale, //
654  preroll_point, //
655  preroll_matrix,
656  std::nullopt //
657  );
658  }
659 
660  // Now simulate rendering with a slightly different scale factor.
661  RenderTarget render_target =
662  aiks_context.GetContentContext()
663  .GetRenderTargetCache()
664  ->CreateOffscreenMSAA(*aiks_context.GetContext(), {100, 100}, 1);
665 
666  TextContents text_contents;
667  text_contents.SetTextFrame(text_frame);
668  text_contents.SetOffset(preroll_point);
669  text_contents.SetScale(1.6);
670  text_contents.SetColor(Color::Aqua());
671 
672  Matrix not_preroll_matrix =
673  Matrix::MakeTranslateScale({1.5, 1.5, 1}, {100, 50, 0});
674 
675  Entity entity;
676  entity.SetTransform(not_preroll_matrix);
677 
678  std::shared_ptr<CommandBuffer> command_buffer =
679  aiks_context.GetContext()->CreateCommandBuffer();
680  std::shared_ptr<RenderPass> render_pass =
681  command_buffer->CreateRenderPass(render_target);
682 
683  EXPECT_TRUE(text_contents.Render(aiks_context.GetContentContext(), entity,
684  *render_pass));
685 }

References impeller::AiksContext::GetContentContext(), impeller::AiksContext::GetContext(), impeller::ContentContext::GetLazyGlyphAtlas(), impeller::ContentContext::GetRenderTargetCache(), impeller::MakeTextFrameFromTextBlobSkia(), impeller::TextContents::Render(), scale, impeller::TextContents::SetColor(), impeller::TextContents::SetOffset(), impeller::TextContents::SetScale(), impeller::TextContents::SetTextFrame(), and impeller::Entity::SetTransform().

◆ TEST_P() [261/497]

impeller::testing::TEST_P ( AiksTest  ,
TextForegroundShaderWithTransform   
)

Definition at line 507 of file aiks_dl_text_unittests.cc.

507  {
508  auto mapping = flutter::testing::OpenFixtureAsSkData("Roboto-Regular.ttf");
509  ASSERT_NE(mapping, nullptr);
510 
511  Scalar font_size = 100;
512  sk_sp<SkFontMgr> font_mgr = txt::GetDefaultFontManager();
513  SkFont sk_font(font_mgr->makeFromData(mapping), font_size);
514 
515  DlPaint text_paint;
516  text_paint.setColor(DlColor::kBlue());
517 
518  std::vector<DlColor> colors = {DlColor::RGBA(0.9568, 0.2627, 0.2118, 1.0),
519  DlColor::RGBA(0.1294, 0.5882, 0.9529, 1.0)};
520  std::vector<Scalar> stops = {
521  0.0,
522  1.0,
523  };
524  text_paint.setColorSource(DlColorSource::MakeLinear(
525  /*start_point=*/DlPoint(0, 0), //
526  /*end_point=*/DlPoint(100, 100), //
527  /*stop_count=*/2, //
528  /*colors=*/colors.data(), //
529  /*stops=*/stops.data(), //
530  /*tile_mode=*/DlTileMode::kRepeat //
531  ));
532 
533  DisplayListBuilder builder;
534  builder.Translate(100, 100);
535  builder.Rotate(45);
536 
537  auto blob = SkTextBlob::MakeFromString("Hello", sk_font);
538  ASSERT_NE(blob, nullptr);
539  auto frame = MakeTextFrameFromTextBlobSkia(blob);
540  builder.DrawTextFrame(frame, 0, 0, text_paint);
541 
542  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
543 }

References impeller::MakeTextFrameFromTextBlobSkia().

◆ TEST_P() [262/497]

impeller::testing::TEST_P ( AiksTest  ,
TextFrameSubpixelAlignment   
)

Definition at line 229 of file aiks_dl_text_unittests.cc.

229  {
230  // "Random" numbers between 0 and 1. Hardcoded to avoid flakiness in goldens.
231  std::array<Scalar, 20> phase_offsets = {
232  7.82637e-06, 0.131538, 0.755605, 0.45865, 0.532767,
233  0.218959, 0.0470446, 0.678865, 0.679296, 0.934693,
234  0.383502, 0.519416, 0.830965, 0.0345721, 0.0534616,
235  0.5297, 0.671149, 0.00769819, 0.383416, 0.0668422};
236  auto callback = [&]() -> sk_sp<DisplayList> {
237  static float font_size = 20;
238  static float phase_variation = 0.2;
239  static float speed = 0.5;
240  static float magnitude = 100;
241  if (AiksTest::ImGuiBegin("Controls", nullptr,
242  ImGuiWindowFlags_AlwaysAutoResize)) {
243  ImGui::SliderFloat("Font size", &font_size, 5, 50);
244  ImGui::SliderFloat("Phase variation", &phase_variation, 0, 1);
245  ImGui::SliderFloat("Oscillation speed", &speed, 0, 2);
246  ImGui::SliderFloat("Oscillation magnitude", &magnitude, 0, 300);
247  ImGui::End();
248  }
249 
250  DisplayListBuilder builder;
251  builder.Scale(GetContentScale().x, GetContentScale().y);
252 
253  for (size_t i = 0; i < phase_offsets.size(); i++) {
254  SkPoint position = SkPoint::Make(
255  200 +
256  magnitude * std::sin((-phase_offsets[i] * k2Pi * phase_variation +
257  GetSecondsElapsed() * speed)), //
258  200 + i * font_size * 1.1 //
259  );
261  GetContext(), builder,
262  "the quick brown fox jumped over "
263  "the lazy dog!.?",
264  "Roboto-Regular.ttf",
265  {.font_size = font_size, .position = position})) {
266  return nullptr;
267  }
268  }
269  return builder.Build();
270  };
271 
272  ASSERT_TRUE(OpenPlaygroundHere(callback));
273 }

References impeller::k2Pi, RenderTextInCanvasSkia(), and x.

◆ TEST_P() [263/497]

impeller::testing::TEST_P ( AiksTest  ,
TextRotated   
)

Definition at line 401 of file aiks_dl_text_unittests.cc.

401  {
402  DisplayListBuilder builder;
403 
404  builder.Scale(GetContentScale().x, GetContentScale().y);
405  DlPaint paint;
406  paint.setColor(DlColor::ARGB(0.1, 0.1, 0.1, 1.0));
407  builder.DrawPaint(paint);
408 
409  builder.Transform(SkM44::ColMajor(Matrix(0.25, -0.3, 0, -0.002, //
410  0, 0.5, 0, 0, //
411  0, 0, 0.3, 0, //
412  100, 100, 0, 1.3)
413  .m));
414  ASSERT_TRUE(RenderTextInCanvasSkia(
415  GetContext(), builder, "the quick brown fox jumped over the lazy dog!.?",
416  "Roboto-Regular.ttf"));
417 
418  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
419 }

References RenderTextInCanvasSkia(), and x.

◆ TEST_P() [264/497]

impeller::testing::TEST_P ( AiksTest  ,
TextRotated180Degrees   
)

Definition at line 191 of file aiks_dl_text_unittests.cc.

191  {
192  float fpivot[2] = {200 + 30, 200 - 20};
193  float rotation = 180;
194  float foffset[2] = {200, 200};
195 
196  auto callback = [&]() -> sk_sp<DisplayList> {
197  if (AiksTest::ImGuiBegin("Controls", nullptr,
198  ImGuiWindowFlags_AlwaysAutoResize)) {
199  ImGui::SliderFloat("pivotx", &fpivot[0], 0, 300);
200  ImGui::SliderFloat("pivoty", &fpivot[1], 0, 300);
201  ImGui::SliderFloat("rotation", &rotation, 0, 360);
202  ImGui::SliderFloat("foffsetx", &foffset[0], 0, 300);
203  ImGui::SliderFloat("foffsety", &foffset[1], 0, 300);
204  ImGui::End();
205  }
206  DisplayListBuilder builder;
207  builder.Scale(GetContentScale().x, GetContentScale().y);
208  builder.DrawPaint(DlPaint().setColor(DlColor(0xffffeeff)));
209 
210  builder.Save();
211  DlPoint pivot = Point(fpivot[0], fpivot[1]);
212  builder.Translate(pivot.x, pivot.y);
213  builder.Rotate(rotation);
214  builder.Translate(-pivot.x, -pivot.y);
215 
217  GetContext(), builder, "test", "Roboto-Regular.ttf",
218  TextRenderOptions{
219  .color = DlColor::kBlack(),
220  .position = SkPoint::Make(foffset[0], foffset[1]),
221  });
222 
223  builder.Restore();
224  return builder.Build();
225  };
226  ASSERT_TRUE(OpenPlaygroundHere(callback));
227 }

References impeller::testing::TextRenderOptions::color, RenderTextInCanvasSkia(), and x.

◆ TEST_P() [265/497]

impeller::testing::TEST_P ( AiksTest  ,
ToImageFromImage   
)

Definition at line 1055 of file aiks_dl_unittests.cc.

1055  {
1056  DisplayListBuilder builder;
1057  Path ip_path = PathBuilder{}
1058  .AddArc(DlRect::MakeLTRB(0, 0, 100, 100), Radians(0),
1059  Radians(3.14 / 2))
1060  .TakePath();
1061  DlPath path = DlPath(ip_path);
1062 
1063  builder.DrawPath(path, DlPaint().setColor(DlColor::kRed()));
1064 
1065  AiksContext renderer(GetContext(), nullptr);
1066  auto texture =
1067  DisplayListToTexture(builder.Build(), ISize(100, 100), renderer);
1068 
1069  // First, Readback the texture data into a host buffer.
1071  desc.size = texture->GetTextureDescriptor().GetByteSizeOfBaseMipLevel();
1072  desc.readback = true;
1073  desc.storage_mode = StorageMode::kHostVisible;
1074 
1075  auto device_buffer = GetContext()->GetResourceAllocator()->CreateBuffer(desc);
1076  {
1077  auto cmd_buffer = GetContext()->CreateCommandBuffer();
1078  auto blit_pass = cmd_buffer->CreateBlitPass();
1079 
1080  blit_pass->AddCopy(texture, device_buffer);
1081  blit_pass->EncodeCommands();
1082 
1083  auto latch = std::make_shared<fml::CountDownLatch>(1u);
1084  GetContext()->GetCommandQueue()->Submit(
1085  {cmd_buffer},
1086  [latch](CommandBuffer::Status status) { latch->CountDown(); });
1087  latch->Wait();
1088  }
1089 
1090  impeller::TextureDescriptor tex_desc = texture->GetTextureDescriptor();
1091  auto reupload_texture =
1092  GetContext()->GetResourceAllocator()->CreateTexture(tex_desc);
1093 
1094  // Next, Re-upload the data into a new texture.
1095  {
1096  auto cmd_buffer = GetContext()->CreateCommandBuffer();
1097  auto blit_pass = cmd_buffer->CreateBlitPass();
1098  blit_pass->AddCopy(DeviceBuffer::AsBufferView(device_buffer),
1099  reupload_texture);
1100  blit_pass->ConvertTextureToShaderRead(texture);
1101  blit_pass->EncodeCommands();
1102 
1103  auto latch = std::make_shared<fml::CountDownLatch>(1u);
1104  GetContext()->GetCommandQueue()->Submit(
1105  {cmd_buffer},
1106  [latch](CommandBuffer::Status status) { latch->CountDown(); });
1107  latch->Wait();
1108  }
1109 
1110  // Draw the results side by side. These should look the same.
1111  DisplayListBuilder canvas;
1112  DlPaint paint = DlPaint();
1113  canvas.DrawRect(
1114  DlRect::MakeLTRB(0, 0, 100, 100),
1115  DlPaint().setColor(DlColor::kBlue()).setDrawStyle(DlDrawStyle::kStroke));
1116  canvas.DrawImage(DlImageImpeller::Make(texture), DlPoint(0, 0),
1117  DlImageSampling::kNearestNeighbor, &paint);
1118 
1119  canvas.DrawRect(
1120  DlRect::MakeLTRB(0, 100, 100, 200),
1121  DlPaint().setColor(DlColor::kRed()).setDrawStyle(DlDrawStyle::kStroke));
1122  canvas.DrawImage(DlImageImpeller::Make(reupload_texture), DlPoint(0, 100),
1123  DlImageSampling::kNearestNeighbor, &paint);
1124  OpenPlaygroundHere(canvas.Build());
1125 }

References impeller::PathBuilder::AddArc(), impeller::DeviceBuffer::AsBufferView(), impeller::DisplayListToTexture(), impeller::kHostVisible, impeller::DlImageImpeller::Make(), impeller::DeviceBufferDescriptor::readback, impeller::DeviceBufferDescriptor::size, impeller::DeviceBufferDescriptor::storage_mode, and impeller::PathBuilder::TakePath().

◆ TEST_P() [266/497]

impeller::testing::TEST_P ( AiksTest  ,
TransformMultipliesCorrectly   
)

Definition at line 69 of file canvas_unittests.cc.

69  {
70  ContentContext context(GetContext(), nullptr);
71  auto canvas = CreateTestCanvas(context);
72 
73  ASSERT_MATRIX_NEAR(canvas->GetCurrentTransform(), Matrix());
74 
75  // clang-format off
76  canvas->Translate(Vector3(100, 200));
78  canvas->GetCurrentTransform(),
79  Matrix( 1, 0, 0, 0,
80  0, 1, 0, 0,
81  0, 0, 1, 0,
82  100, 200, 0, 1));
83 
84  canvas->Rotate(Radians(kPiOver2));
86  canvas->GetCurrentTransform(),
87  Matrix( 0, 1, 0, 0,
88  -1, 0, 0, 0,
89  0, 0, 1, 0,
90  100, 200, 0, 1));
91 
92  canvas->Scale(Vector3(2, 3));
94  canvas->GetCurrentTransform(),
95  Matrix( 0, 2, 0, 0,
96  -3, 0, 0, 0,
97  0, 0, 0, 0,
98  100, 200, 0, 1));
99 
100  canvas->Translate(Vector3(100, 200));
102  canvas->GetCurrentTransform(),
103  Matrix( 0, 2, 0, 0,
104  -3, 0, 0, 0,
105  0, 0, 0, 0,
106  -500, 400, 0, 1));
107  // clang-format on
108 }

References ASSERT_MATRIX_NEAR, CreateTestCanvas(), and impeller::kPiOver2.

◆ TEST_P() [267/497]

impeller::testing::TEST_P ( AiksTest  ,
TranslucentSaveLayerDrawsCorrectly   
)

Definition at line 147 of file aiks_dl_unittests.cc.

147  {
148  DisplayListBuilder builder(GetCullRect(GetWindowSize()));
149 
150  DlPaint paint;
151  paint.setColor(DlColor::kBlue());
152  builder.DrawRect(SkRect::MakeXYWH(100, 100, 300, 300), paint);
153 
154  DlPaint save_paint;
155  save_paint.setColor(DlColor::kBlack().withAlpha(128));
156  builder.SaveLayer(nullptr, &save_paint);
157  builder.DrawRect(SkRect::MakeXYWH(100, 500, 300, 300), paint);
158  builder.Restore();
159 
160  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
161 }

◆ TEST_P() [268/497]

impeller::testing::TEST_P ( AiksTest  ,
TranslucentSaveLayerImageDrawsCorrectly   
)

Definition at line 258 of file aiks_dl_unittests.cc.

258  {
259  DisplayListBuilder builder(GetCullRect(GetWindowSize()));
260 
261  auto image = DlImageImpeller::Make(CreateTextureForFixture("airplane.jpg"));
262  builder.DrawImage(image, SkPoint{100, 100}, DlImageSampling::kMipmapLinear);
263 
264  DlPaint paint;
265  paint.setColor(DlColor::kBlack().withAlpha(128));
266  builder.SaveLayer(nullptr, &paint);
267  builder.DrawImage(image, SkPoint{100, 500}, DlImageSampling::kMipmapLinear);
268  builder.Restore();
269 
270  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
271 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [269/497]

impeller::testing::TEST_P ( AiksTest  ,
TranslucentSaveLayerWithAdvancedBlendModeDrawsCorrectly   
)

Definition at line 343 of file aiks_dl_unittests.cc.

343  {
344  DisplayListBuilder builder(GetCullRect(GetWindowSize()));
345 
346  DlPaint paint;
347  paint.setColor(DlColor::kRed());
348  builder.DrawRect(SkRect::MakeXYWH(0, 0, 400, 400), paint);
349 
350  DlPaint save_paint;
351  save_paint.setAlpha(128);
352  save_paint.setBlendMode(DlBlendMode::kLighten);
353  builder.SaveLayer(nullptr, &save_paint);
354 
355  DlPaint draw_paint;
356  draw_paint.setColor(DlColor::kGreen());
357  builder.DrawCircle(SkPoint{200, 200}, 100, draw_paint);
358  builder.Restore();
359 
360  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
361 }

◆ TEST_P() [270/497]

impeller::testing::TEST_P ( AiksTest  ,
TranslucentSaveLayerWithBlendColorFilterDrawsCorrectly   
)

Definition at line 163 of file aiks_dl_unittests.cc.

163  {
164  DisplayListBuilder builder(GetCullRect(GetWindowSize()));
165 
166  DlPaint paint;
167  paint.setColor(DlColor::kBlue());
168  builder.DrawRect(SkRect::MakeXYWH(100, 100, 300, 300), paint);
169 
170  DlPaint save_paint;
171  paint.setColor(DlColor::kBlack().withAlpha(128));
172  paint.setColorFilter(
173  DlColorFilter::MakeBlend(DlColor::kRed(), DlBlendMode::kDstOver));
174  builder.Save();
175  builder.ClipRect(SkRect::MakeXYWH(100, 500, 300, 300));
176  builder.SaveLayer(nullptr, &paint);
177 
178  DlPaint draw_paint;
179  draw_paint.setColor(DlColor::kBlue());
180  builder.DrawRect(SkRect::MakeXYWH(100, 500, 300, 300), draw_paint);
181  builder.Restore();
182  builder.Restore();
183 
184  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
185 }

◆ TEST_P() [271/497]

impeller::testing::TEST_P ( AiksTest  ,
TranslucentSaveLayerWithBlendImageFilterDrawsCorrectly   
)

Definition at line 187 of file aiks_dl_unittests.cc.

187  {
188  DisplayListBuilder builder(GetCullRect(GetWindowSize()));
189 
190  DlPaint paint;
191  paint.setColor(DlColor::kBlue());
192  builder.DrawRect(SkRect::MakeXYWH(100, 100, 300, 300), paint);
193 
194  DlPaint save_paint;
195  save_paint.setColor(DlColor::kBlack().withAlpha(128));
196  save_paint.setImageFilter(DlImageFilter::MakeColorFilter(
197  DlColorFilter::MakeBlend(DlColor::kRed(), DlBlendMode::kDstOver)));
198 
199  builder.SaveLayer(nullptr, &save_paint);
200 
201  DlPaint draw_paint;
202  draw_paint.setColor(DlColor::kBlue());
203  builder.DrawRect(SkRect::MakeXYWH(100, 500, 300, 300), draw_paint);
204  builder.Restore();
205 
206  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
207 }

◆ TEST_P() [272/497]

impeller::testing::TEST_P ( AiksTest  ,
TranslucentSaveLayerWithColorAndImageFilterDrawsCorrectly   
)

Definition at line 209 of file aiks_dl_unittests.cc.

209  {
210  DisplayListBuilder builder(GetCullRect(GetWindowSize()));
211 
212  DlPaint paint;
213  paint.setColor(DlColor::kBlue());
214  builder.DrawRect(SkRect::MakeXYWH(100, 100, 300, 300), paint);
215 
216  DlPaint save_paint;
217  save_paint.setColor(DlColor::kBlack().withAlpha(128));
218  save_paint.setColorFilter(
219  DlColorFilter::MakeBlend(DlColor::kRed(), DlBlendMode::kDstOver));
220  builder.Save();
221  builder.ClipRect(SkRect::MakeXYWH(100, 500, 300, 300));
222  builder.SaveLayer(nullptr, &save_paint);
223 
224  DlPaint draw_paint;
225  draw_paint.setColor(DlColor::kBlue());
226  builder.DrawRect(SkRect::MakeXYWH(100, 500, 300, 300), draw_paint);
227  builder.Restore();
228  builder.Restore();
229 
230  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
231 }

◆ TEST_P() [273/497]

impeller::testing::TEST_P ( AiksTest  ,
TranslucentSaveLayerWithColorFilterAndImageFilterDrawsCorrectly   
)

Definition at line 317 of file aiks_dl_unittests.cc.

318  {
319  DisplayListBuilder builder(GetCullRect(GetWindowSize()));
320 
321  auto image = DlImageImpeller::Make(CreateTextureForFixture("airplane.jpg"));
322  builder.DrawImage(image, SkPoint{100, 100}, {});
323 
324  const float matrix[20] = {
325  1, 0, 0, 0, 0, //
326  0, 1, 0, 0, 0, //
327  0, 0.2, 1, 0, 0, //
328  0, 0, 0, 0.5, 0 //
329  };
330  DlPaint paint;
331  paint.setColor(DlColor::kBlack().withAlpha(128));
332  paint.setImageFilter(
333  DlImageFilter::MakeColorFilter(DlColorFilter::MakeMatrix(matrix)));
334  paint.setColorFilter(
335  DlColorFilter::MakeBlend(DlColor::kGreen(), DlBlendMode::kModulate));
336  builder.SaveLayer(nullptr, &paint);
337  builder.DrawImage(image, SkPoint{100, 500}, {});
338  builder.Restore();
339 
340  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
341 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [274/497]

impeller::testing::TEST_P ( AiksTest  ,
TranslucentSaveLayerWithColorMatrixColorFilterDrawsCorrectly   
)

Definition at line 273 of file aiks_dl_unittests.cc.

273  {
274  DisplayListBuilder builder(GetCullRect(GetWindowSize()));
275 
276  auto image = DlImageImpeller::Make(CreateTextureForFixture("airplane.jpg"));
277  builder.DrawImage(image, SkPoint{100, 100}, {});
278 
279  const float matrix[20] = {
280  1, 0, 0, 0, 0, //
281  0, 1, 0, 0, 0, //
282  0, 0, 1, 0, 0, //
283  0, 0, 0, 2, 0 //
284  };
285  DlPaint paint;
286  paint.setColor(DlColor::kBlack().withAlpha(128));
287  paint.setColorFilter(DlColorFilter::MakeMatrix(matrix));
288  builder.SaveLayer(nullptr, &paint);
289  builder.DrawImage(image, SkPoint{100, 500}, {});
290  builder.Restore();
291 
292  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
293 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [275/497]

impeller::testing::TEST_P ( AiksTest  ,
TranslucentSaveLayerWithColorMatrixImageFilterDrawsCorrectly   
)

Definition at line 295 of file aiks_dl_unittests.cc.

295  {
296  DisplayListBuilder builder(GetCullRect(GetWindowSize()));
297 
298  auto image = DlImageImpeller::Make(CreateTextureForFixture("airplane.jpg"));
299  builder.DrawImage(image, SkPoint{100, 100}, {});
300 
301  const float matrix[20] = {
302  1, 0, 0, 0, 0, //
303  0, 1, 0, 0, 0, //
304  0, 0, 1, 0, 0, //
305  0, 0, 0, 2, 0 //
306  };
307  DlPaint paint;
308  paint.setColor(DlColor::kBlack().withAlpha(128));
309  paint.setColorFilter(DlColorFilter::MakeMatrix(matrix));
310  builder.SaveLayer(nullptr, &paint);
311  builder.DrawImage(image, SkPoint{100, 500}, {});
312  builder.Restore();
313 
314  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
315 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [276/497]

impeller::testing::TEST_P ( AiksTest  ,
TransparentShadowProducesCorrectColor   
)

Definition at line 868 of file aiks_dl_unittests.cc.

868  {
869  DisplayListBuilder builder;
870  builder.Save();
871  builder.Scale(1.618, 1.618);
872  SkPath path = SkPath{}.addRect(SkRect::MakeXYWH(0, 0, 200, 100));
873 
874  builder.DrawShadow(path, flutter::DlColor::kTransparent(), 15, false, 1);
875  builder.Restore();
876 
877  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
878 }

◆ TEST_P() [277/497]

impeller::testing::TEST_P ( AiksTest  ,
VerifyNonOptimizedGradient   
)

Definition at line 924 of file aiks_dl_gradient_unittests.cc.

924  {
925  DisplayListBuilder builder;
926  DlPaint paint;
927  builder.Translate(100.0f, 0);
928 
929  std::vector<DlColor> colors = {DlColor::kRed(), DlColor::kBlue(),
930  DlColor::kGreen()};
931  std::vector<Scalar> stops = {0.0, 0.1, 1.0};
932 
933  // Inset the start and end point to verify that we do not apply
934  // the fast gradient condition.
935  paint.setColorSource(
936  DlColorSource::MakeLinear({0, 150}, {0, 100}, stops.size(), colors.data(),
937  stops.data(), DlTileMode::kRepeat));
938 
939  paint.setColor(DlColor::kWhite());
940  builder.DrawRect(SkRect::MakeXYWH(0, 0, 300, 300), paint);
941  builder.Translate(400, 0);
942  builder.DrawRRect(SkRRect::MakeRectXY(SkRect::MakeXYWH(0, 0, 300, 300), 4, 4),
943  paint);
944 
945  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
946 }

◆ TEST_P() [278/497]

impeller::testing::TEST_P ( AiksTest  ,
VerticesGeometryColorUVPositionData   
)

Definition at line 96 of file aiks_dl_vertices_unittests.cc.

96  {
97  DisplayListBuilder builder;
98  DlPaint paint;
99  auto image =
100  DlImageImpeller::Make(CreateTextureForFixture("table_mountain_nx.png"));
101  auto size = image->impeller_texture()->GetSize();
102 
103  paint.setColorSource(
104  DlColorSource::MakeImage(image, DlTileMode::kClamp, DlTileMode::kClamp));
105 
106  std::vector<DlPoint> positions = {
107  DlPoint(0, 0), DlPoint(size.width, 0),
108  DlPoint(0, size.height), DlPoint(size.width, 0),
109  DlPoint(0, 0), DlPoint(size.width, size.height),
110  };
111  std::vector<DlColor> colors = {
112  DlColor::kRed().withAlpha(128), DlColor::kBlue().withAlpha(128),
113  DlColor::kGreen().withAlpha(128), DlColor::kRed().withAlpha(128),
114  DlColor::kBlue().withAlpha(128), DlColor::kGreen().withAlpha(128),
115  };
116 
117  auto vertices =
118  MakeVertices(DlVertexMode::kTriangles, positions, {}, {}, colors);
119 
120  builder.DrawVertices(vertices, DlBlendMode::kDstOver, paint);
121  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
122 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [279/497]

impeller::testing::TEST_P ( AiksTest  ,
VerticesGeometryColorUVPositionDataAdvancedBlend   
)

Definition at line 124 of file aiks_dl_vertices_unittests.cc.

124  {
125  DisplayListBuilder builder;
126  DlPaint paint;
127  auto image =
128  DlImageImpeller::Make(CreateTextureForFixture("table_mountain_nx.png"));
129  auto size = image->impeller_texture()->GetSize();
130 
131  paint.setColorSource(
132  DlColorSource::MakeImage(image, DlTileMode::kClamp, DlTileMode::kClamp));
133 
134  std::vector<DlPoint> positions = {
135  DlPoint(0, 0), DlPoint(size.width, 0),
136  DlPoint(0, size.height), DlPoint(size.width, 0),
137  DlPoint(0, 0), DlPoint(size.width, size.height),
138  };
139  std::vector<DlColor> colors = {
140  DlColor::kRed().modulateOpacity(0.5),
141  DlColor::kBlue().modulateOpacity(0.5),
142  DlColor::kGreen().modulateOpacity(0.5),
143  DlColor::kRed().modulateOpacity(0.5),
144  DlColor::kBlue().modulateOpacity(0.5),
145  DlColor::kGreen().modulateOpacity(0.5),
146  };
147 
148  auto vertices =
149  MakeVertices(DlVertexMode::kTriangles, positions, {}, {}, colors);
150 
151  builder.DrawVertices(vertices, DlBlendMode::kColorBurn, paint);
152  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
153 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [280/497]

impeller::testing::TEST_P ( AiksTest  ,
VerticesGeometryUVPositionData   
)

Definition at line 48 of file aiks_dl_vertices_unittests.cc.

48  {
49  DisplayListBuilder builder;
50  DlPaint paint;
51  auto image =
52  DlImageImpeller::Make(CreateTextureForFixture("table_mountain_nx.png"));
53  auto size = image->impeller_texture()->GetSize();
54 
55  paint.setColorSource(
56  DlColorSource::MakeImage(image, DlTileMode::kClamp, DlTileMode::kClamp));
57 
58  std::vector<DlPoint> vertex_coordinates = {
59  DlPoint(0, 0),
60  DlPoint(size.width, 0),
61  DlPoint(0, size.height),
62  };
63  auto vertices = MakeVertices(DlVertexMode::kTriangleStrip, vertex_coordinates,
64  {0, 1, 2}, {}, {});
65 
66  builder.DrawVertices(vertices, DlBlendMode::kSrcOver, paint);
67  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
68 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [281/497]

impeller::testing::TEST_P ( AiksTest  ,
VerticesGeometryUVPositionDataWithTranslate   
)

Definition at line 71 of file aiks_dl_vertices_unittests.cc.

71  {
72  DisplayListBuilder builder;
73  DlPaint paint;
74  auto image =
75  DlImageImpeller::Make(CreateTextureForFixture("table_mountain_nx.png"));
76  auto size = image->impeller_texture()->GetSize();
77 
78  DlMatrix matrix = DlMatrix::MakeTranslation({100, 100});
79  paint.setColorSource(
80  DlColorSource::MakeImage(image, DlTileMode::kClamp, DlTileMode::kClamp,
81  DlImageSampling::kLinear, &matrix));
82 
83  std::vector<DlPoint> positions = {
84  DlPoint(0, 0),
85  DlPoint(size.width, 0),
86  DlPoint(0, size.height),
87  };
88  auto vertices =
89  MakeVertices(DlVertexMode::kTriangleStrip, positions, {0, 1, 2}, {}, {});
90 
91  builder.DrawVertices(vertices, DlBlendMode::kSrcOver, paint);
92  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
93 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [282/497]

impeller::testing::TEST_P ( AllocatorMTLTest  ,
DebugTraceMemoryStatistics   
)

Definition at line 28 of file allocator_mtl_unittests.mm.

28  {
29  auto& context_mtl = ContextMTL::Cast(*GetContext());
30  const auto& allocator = context_mtl.GetResourceAllocator();
31 
32  EXPECT_EQ(allocator->DebugGetHeapUsage().ConvertTo<MebiBytes>().GetSize(),
33  0u);
34 
35  // Memoryless texture does not increase allocated size.
36  {
37  TextureDescriptor desc;
38  desc.format = PixelFormat::kR8G8B8A8UNormInt;
39  desc.storage_mode = StorageMode::kDeviceTransient;
40  desc.size = {1024, 1024};
41  auto texture_1 = allocator->CreateTexture(desc);
42 
43  // Private storage texture increases allocated size.
44  desc.storage_mode = StorageMode::kDevicePrivate;
45  auto texture_2 = allocator->CreateTexture(desc);
46 
47 #ifdef IMPELLER_DEBUG
48  EXPECT_EQ(allocator->DebugGetHeapUsage().ConvertTo<MebiBytes>().GetSize(),
49  4u);
50 #else
51  EXPECT_EQ(allocator->DebugGetHeapUsage().ConvertTo<MebiBytes>().GetSize(),
52  0u);
53 #endif // IMPELLER_DEBUG
54 
55  // Host storage texture increases allocated size.
56  desc.storage_mode = StorageMode::kHostVisible;
57  auto texture_3 = allocator->CreateTexture(desc);
58 
59 #ifdef IMPELLER_DEBUG
60  EXPECT_EQ(allocator->DebugGetHeapUsage().ConvertTo<MebiBytes>().GetSize(),
61  8u);
62 #else
63  EXPECT_EQ(allocator->DebugGetHeapUsage().ConvertTo<MebiBytes>().GetSize(),
64  0u);
65 #endif // IMPELLER_DEBUG
66  }
67 
68  // After all textures are out of scope, memory has been decremented.
69  EXPECT_EQ(allocator->DebugGetHeapUsage().ConvertTo<MebiBytes>().GetSize(),
70  0u);
71 }

References impeller::BackendCast< ContextMTL, Context >::Cast(), impeller::TextureDescriptor::format, impeller::AllocationSize< Period >::GetSize(), impeller::kDevicePrivate, impeller::kDeviceTransient, impeller::kHostVisible, impeller::kR8G8B8A8UNormInt, impeller::TextureDescriptor::size, and impeller::TextureDescriptor::storage_mode.

◆ TEST_P() [283/497]

impeller::testing::TEST_P ( BlendFilterContentsTest  ,
AdvancedBlendColorAlignsColorTo4   
)

Definition at line 45 of file blend_filter_contents_unittests.cc.

45  {
46  std::shared_ptr<Texture> texture = MakeTexture(ISize(100, 100));
47  BlendFilterContents filter_contents;
48  filter_contents.SetInputs({FilterInput::Make(texture)});
49  filter_contents.SetForegroundColor(Color(1.0, 0.0, 0.0, 1.0));
50  filter_contents.SetBlendMode(BlendMode::kColorDodge);
51 
52  std::shared_ptr<ContentContext> renderer = GetContentContext();
53  // Add random byte to get the HostBuffer in a bad alignment.
54  uint8_t byte = 0xff;
55  BufferView buffer_view =
56  renderer->GetTransientsBuffer().Emplace(&byte, /*length=*/1, /*align=*/1);
57  EXPECT_EQ(buffer_view.GetRange().offset, 4u);
58  EXPECT_EQ(buffer_view.GetRange().length, 1u);
59  Entity entity;
60 
61  std::optional<Entity> result = filter_contents.GetEntity(
62  *renderer, entity, /*coverage_hint=*/std::nullopt);
63 
64  EXPECT_TRUE(result.has_value());
65 }

References buffer_view, impeller::FilterContents::GetEntity(), impeller::kColorDodge, impeller::FilterInput::Make(), impeller::BlendFilterContents::SetBlendMode(), impeller::BlendFilterContents::SetForegroundColor(), and impeller::FilterContents::SetInputs().

◆ TEST_P() [284/497]

impeller::testing::TEST_P ( BlitPassTest  ,
BlitAcrossDifferentPixelFormatsFails   
)

Definition at line 30 of file blit_pass_unittests.cc.

30  {
31  ScopedValidationDisable scope; // avoid noise in output.
32  auto context = GetContext();
33  auto cmd_buffer = context->CreateCommandBuffer();
34  auto blit_pass = cmd_buffer->CreateBlitPass();
35 
36  TextureDescriptor src_desc;
37  src_desc.format = PixelFormat::kA8UNormInt;
38  src_desc.size = {100, 100};
39  src_desc.storage_mode = StorageMode::kHostVisible;
40  auto src = context->GetResourceAllocator()->CreateTexture(src_desc);
41 
42  TextureDescriptor dst_format;
43  dst_format.format = PixelFormat::kR8G8B8A8UNormInt;
44  dst_format.size = {100, 100};
45  dst_format.storage_mode = StorageMode::kHostVisible;
46  auto dst = context->GetResourceAllocator()->CreateTexture(dst_format);
47 
48  EXPECT_FALSE(blit_pass->AddCopy(src, dst));
49 }

References impeller::TextureDescriptor::format, impeller::kA8UNormInt, impeller::kHostVisible, impeller::kR8G8B8A8UNormInt, impeller::TextureDescriptor::size, and impeller::TextureDescriptor::storage_mode.

◆ TEST_P() [285/497]

impeller::testing::TEST_P ( BlitPassTest  ,
BlitAcrossDifferentSampleCountsFails   
)

Definition at line 51 of file blit_pass_unittests.cc.

51  {
52  ScopedValidationDisable scope; // avoid noise in output.
53  auto context = GetContext();
54  auto cmd_buffer = context->CreateCommandBuffer();
55  auto blit_pass = cmd_buffer->CreateBlitPass();
56 
57  TextureDescriptor src_desc;
58  src_desc.format = PixelFormat::kR8G8B8A8UNormInt;
59  src_desc.sample_count = SampleCount::kCount4;
60  src_desc.size = {100, 100};
61  auto src = context->GetResourceAllocator()->CreateTexture(src_desc);
62 
63  TextureDescriptor dst_format;
64  dst_format.format = PixelFormat::kR8G8B8A8UNormInt;
65  dst_format.size = {100, 100};
66  auto dst = context->GetResourceAllocator()->CreateTexture(dst_format);
67 
68  EXPECT_FALSE(blit_pass->AddCopy(src, dst));
69 }

References impeller::TextureDescriptor::format, impeller::kCount4, impeller::kR8G8B8A8UNormInt, impeller::TextureDescriptor::sample_count, and impeller::TextureDescriptor::size.

◆ TEST_P() [286/497]

impeller::testing::TEST_P ( BlitPassTest  ,
BlitPassesForMatchingFormats   
)

Definition at line 71 of file blit_pass_unittests.cc.

71  {
72  ScopedValidationDisable scope; // avoid noise in output.
73  auto context = GetContext();
74  auto cmd_buffer = context->CreateCommandBuffer();
75  auto blit_pass = cmd_buffer->CreateBlitPass();
76 
77  TextureDescriptor src_desc;
78  src_desc.format = PixelFormat::kR8G8B8A8UNormInt;
79  src_desc.size = {100, 100};
80  src_desc.storage_mode = StorageMode::kHostVisible;
81  auto src = context->GetResourceAllocator()->CreateTexture(src_desc);
82 
83  TextureDescriptor dst_format;
84  dst_format.format = PixelFormat::kR8G8B8A8UNormInt;
85  dst_format.size = {100, 100};
86  dst_format.storage_mode = StorageMode::kHostVisible;
87  auto dst = context->GetResourceAllocator()->CreateTexture(dst_format);
88 
89  EXPECT_TRUE(blit_pass->AddCopy(src, dst));
90 }

References impeller::TextureDescriptor::format, impeller::kHostVisible, impeller::kR8G8B8A8UNormInt, impeller::TextureDescriptor::size, and impeller::TextureDescriptor::storage_mode.

◆ TEST_P() [287/497]

impeller::testing::TEST_P ( BlitPassTest  ,
CanBlitSmallRegionToUninitializedTexture   
)

Definition at line 123 of file blit_pass_unittests.cc.

123  {
124  auto context = GetContext();
125  auto cmd_buffer = context->CreateCommandBuffer();
126  auto blit_pass = cmd_buffer->CreateBlitPass();
127 
128  TextureDescriptor dst_format;
129  dst_format.storage_mode = StorageMode::kDevicePrivate;
130  dst_format.format = PixelFormat::kR8G8B8A8UNormInt;
131  dst_format.size = {1000, 1000};
132  auto dst = context->GetResourceAllocator()->CreateTexture(dst_format);
133 
134  DeviceBufferDescriptor src_format;
135  src_format.size = 4;
136  src_format.storage_mode = StorageMode::kHostVisible;
137  auto src = context->GetResourceAllocator()->CreateBuffer(src_format);
138 
139  ASSERT_TRUE(dst);
140 
141  EXPECT_TRUE(blit_pass->AddCopy(DeviceBuffer::AsBufferView(src), dst,
142  IRect::MakeLTRB(0, 0, 1, 1), "",
143  /*mip_level=*/0, /*slice=*/0));
144  EXPECT_TRUE(blit_pass->EncodeCommands());
145  EXPECT_TRUE(context->GetCommandQueue()->Submit({std::move(cmd_buffer)}).ok());
146 }

References impeller::DeviceBuffer::AsBufferView(), impeller::TextureDescriptor::format, impeller::kDevicePrivate, impeller::kHostVisible, impeller::kR8G8B8A8UNormInt, impeller::TRect< T >::MakeLTRB(), impeller::DeviceBufferDescriptor::size, impeller::TextureDescriptor::size, impeller::DeviceBufferDescriptor::storage_mode, and impeller::TextureDescriptor::storage_mode.

◆ TEST_P() [288/497]

impeller::testing::TEST_P ( BlitPassTest  ,
CanBlitToHigherTextureMipLevels   
)

Definition at line 176 of file blit_pass_unittests.cc.

176  {
177  auto context = GetContext();
178  auto cmd_buffer = context->CreateCommandBuffer();
179  auto blit_pass = cmd_buffer->CreateBlitPass();
180 
181  TextureDescriptor dst_format;
182  dst_format.storage_mode = StorageMode::kDevicePrivate;
183  dst_format.format = PixelFormat::kR8G8B8A8UNormInt;
184  dst_format.size = {1000, 1000};
185  dst_format.mip_count = 4;
186  auto dst = context->GetResourceAllocator()->CreateTexture(dst_format);
187 
188  DeviceBufferDescriptor src_format;
189  src_format.size = 4;
190  src_format.storage_mode = StorageMode::kHostVisible;
191  auto src = context->GetResourceAllocator()->CreateBuffer(src_format);
192 
193  ASSERT_TRUE(dst);
194 
195  EXPECT_TRUE(blit_pass->AddCopy(DeviceBuffer::AsBufferView(src), dst,
196  IRect::MakeLTRB(0, 0, 1, 1), "",
197  /*mip_level=*/1, /*slice=*/0));
198  EXPECT_TRUE(blit_pass->EncodeCommands());
199  EXPECT_TRUE(context->GetCommandQueue()->Submit({std::move(cmd_buffer)}).ok());
200 }

References impeller::DeviceBuffer::AsBufferView(), impeller::TextureDescriptor::format, impeller::kDevicePrivate, impeller::kHostVisible, impeller::kR8G8B8A8UNormInt, impeller::TRect< T >::MakeLTRB(), impeller::TextureDescriptor::mip_count, impeller::DeviceBufferDescriptor::size, impeller::TextureDescriptor::size, impeller::DeviceBufferDescriptor::storage_mode, and impeller::TextureDescriptor::storage_mode.

◆ TEST_P() [289/497]

impeller::testing::TEST_P ( BlitPassTest  ,
CanResizeTextures   
)

Definition at line 202 of file blit_pass_unittests.cc.

202  {
203  auto context = GetContext();
204  auto cmd_buffer = context->CreateCommandBuffer();
205  auto blit_pass = cmd_buffer->CreateBlitPass();
206 
207  TextureDescriptor dst_format;
208  dst_format.storage_mode = StorageMode::kDevicePrivate;
209  dst_format.format = PixelFormat::kR8G8B8A8UNormInt;
210  dst_format.size = {10, 10};
211  dst_format.usage = TextureUsage::kShaderRead | TextureUsage::kShaderWrite;
212  auto dst = context->GetResourceAllocator()->CreateTexture(dst_format);
213 
214  TextureDescriptor src_format;
215  src_format.storage_mode = StorageMode::kDevicePrivate;
216  src_format.format = PixelFormat::kR8G8B8A8UNormInt;
217  src_format.size = {100, 100};
218  auto src = context->GetResourceAllocator()->CreateTexture(src_format);
219 
220  std::vector<uint8_t> bytes(src_format.GetByteSizeOfBaseMipLevel());
221  for (auto i = 0u; i < src_format.GetByteSizeOfBaseMipLevel(); i += 4) {
222  // RGBA
223  bytes[i + 0] = 255;
224  bytes[i + 1] = 0;
225  bytes[i + 2] = 0;
226  bytes[i + 3] = 255;
227  }
228  auto mapping = fml::DataMapping(bytes);
229  auto staging = context->GetResourceAllocator()->CreateBufferWithCopy(mapping);
230 
231  ASSERT_TRUE(dst);
232  ASSERT_TRUE(src);
233  ASSERT_TRUE(staging);
234 
235  EXPECT_TRUE(blit_pass->AddCopy(DeviceBuffer::AsBufferView(staging), src));
236  EXPECT_TRUE(blit_pass->ResizeTexture(src, dst));
237  EXPECT_TRUE(blit_pass->EncodeCommands());
238  EXPECT_TRUE(context->GetCommandQueue()->Submit({std::move(cmd_buffer)}).ok());
239 }

References impeller::DeviceBuffer::AsBufferView(), impeller::TextureDescriptor::format, impeller::TextureDescriptor::GetByteSizeOfBaseMipLevel(), impeller::kDevicePrivate, impeller::kR8G8B8A8UNormInt, impeller::kShaderRead, impeller::kShaderWrite, impeller::TextureDescriptor::size, impeller::TextureDescriptor::storage_mode, and impeller::TextureDescriptor::usage.

◆ TEST_P() [290/497]

impeller::testing::TEST_P ( BlitPassTest  ,
CanResizeTexturesPlayground   
)

Definition at line 241 of file blit_pass_unittests.cc.

241  {
242  auto context = GetContext();
243  auto cmd_buffer = context->CreateCommandBuffer();
244  auto blit_pass = cmd_buffer->CreateBlitPass();
245 
246  std::shared_ptr<Texture> src = CreateTextureForFixture("kalimba.jpg");
247 
248  TextureDescriptor dst_format;
249  dst_format.storage_mode = StorageMode::kDevicePrivate;
250  dst_format.format = PixelFormat::kR8G8B8A8UNormInt;
251  dst_format.size = {src->GetSize().width / 2, src->GetSize().height};
252  dst_format.usage = TextureUsage::kShaderRead | TextureUsage::kShaderWrite;
253  auto dst = context->GetResourceAllocator()->CreateTexture(dst_format);
254 
255  ASSERT_TRUE(dst);
256  ASSERT_TRUE(src);
257 
258  EXPECT_TRUE(blit_pass->ResizeTexture(src, dst));
259  EXPECT_TRUE(blit_pass->EncodeCommands());
260  EXPECT_TRUE(context->GetCommandQueue()->Submit({std::move(cmd_buffer)}).ok());
261 
262  DisplayListBuilder builder;
263  builder.Scale(GetContentScale().x, GetContentScale().y);
264  DlPaint paint;
265  paint.setColor(DlColor::kRed());
266  auto image = DlImageImpeller::Make(dst);
267  builder.DrawImage(image, SkPoint::Make(100.0, 100.0),
268  DlImageSampling::kNearestNeighbor, &paint);
269  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
270 }

References impeller::TextureDescriptor::format, impeller::kDevicePrivate, impeller::kR8G8B8A8UNormInt, impeller::kShaderRead, impeller::kShaderWrite, impeller::DlImageImpeller::Make(), impeller::TextureDescriptor::size, impeller::TextureDescriptor::storage_mode, impeller::TextureDescriptor::usage, impeller::TSize< T >::width, and x.

◆ TEST_P() [291/497]

impeller::testing::TEST_P ( BlitPassTest  ,
ChecksInvalidMipLevelParameter   
)

Definition at line 148 of file blit_pass_unittests.cc.

148  {
149  ScopedValidationDisable scope;
150  auto context = GetContext();
151  auto cmd_buffer = context->CreateCommandBuffer();
152  auto blit_pass = cmd_buffer->CreateBlitPass();
153 
154  TextureDescriptor dst_format;
155  dst_format.storage_mode = StorageMode::kDevicePrivate;
156  dst_format.format = PixelFormat::kR8G8B8A8UNormInt;
157  dst_format.size = {1000, 1000};
158  auto dst = context->GetResourceAllocator()->CreateTexture(dst_format);
159 
160  DeviceBufferDescriptor src_format;
161  src_format.size = 4;
162  src_format.storage_mode = StorageMode::kHostVisible;
163  auto src = context->GetResourceAllocator()->CreateBuffer(src_format);
164 
165  ASSERT_TRUE(dst);
166 
167  EXPECT_FALSE(blit_pass->AddCopy(DeviceBuffer::AsBufferView(src), dst,
168  IRect::MakeLTRB(0, 0, 1, 1), "",
169  /*mip_level=*/1, /*slice=*/0));
170 
171  EXPECT_TRUE(blit_pass->AddCopy(DeviceBuffer::AsBufferView(src), dst,
172  IRect::MakeLTRB(0, 0, 1, 1), "",
173  /*mip_level=*/0, /*slice=*/0));
174 }

References impeller::DeviceBuffer::AsBufferView(), impeller::TextureDescriptor::format, impeller::kDevicePrivate, impeller::kHostVisible, impeller::kR8G8B8A8UNormInt, impeller::TRect< T >::MakeLTRB(), impeller::DeviceBufferDescriptor::size, impeller::TextureDescriptor::size, impeller::DeviceBufferDescriptor::storage_mode, and impeller::TextureDescriptor::storage_mode.

◆ TEST_P() [292/497]

impeller::testing::TEST_P ( BlitPassTest  ,
ChecksInvalidSliceParameters   
)

Definition at line 92 of file blit_pass_unittests.cc.

92  {
93  ScopedValidationDisable scope; // avoid noise in output.
94  auto context = GetContext();
95  auto cmd_buffer = context->CreateCommandBuffer();
96  auto blit_pass = cmd_buffer->CreateBlitPass();
97 
98  TextureDescriptor dst_format;
99  dst_format.storage_mode = StorageMode::kDevicePrivate;
100  dst_format.format = PixelFormat::kR8G8B8A8UNormInt;
101  dst_format.size = {100, 100};
102  auto dst = context->GetResourceAllocator()->CreateTexture(dst_format);
103 
104  DeviceBufferDescriptor src_format;
105  src_format.size = 40000;
106  src_format.storage_mode = StorageMode::kHostVisible;
107  auto src = context->GetResourceAllocator()->CreateBuffer(src_format);
108 
109  ASSERT_TRUE(dst);
110  ASSERT_TRUE(src);
111 
112  EXPECT_FALSE(blit_pass->AddCopy(DeviceBuffer::AsBufferView(src), dst,
113  std::nullopt, "", /*mip_level=*/0,
114  /*slice=*/25));
115  EXPECT_FALSE(blit_pass->AddCopy(DeviceBuffer::AsBufferView(src), dst,
116  std::nullopt, "", /*mip_level=*/0,
117  /*slice=*/6));
118  EXPECT_TRUE(blit_pass->AddCopy(DeviceBuffer::AsBufferView(src), dst,
119  std::nullopt, "", /*mip_level=*/0,
120  /*slice=*/0));
121 }

References impeller::DeviceBuffer::AsBufferView(), impeller::TextureDescriptor::format, impeller::kDevicePrivate, impeller::kHostVisible, impeller::kR8G8B8A8UNormInt, impeller::DeviceBufferDescriptor::size, impeller::TextureDescriptor::size, impeller::DeviceBufferDescriptor::storage_mode, and impeller::TextureDescriptor::storage_mode.

◆ TEST_P() [293/497]

impeller::testing::TEST_P ( ComputeTest  ,
1DThreadgroupSizingIsCorrect   
)

Definition at line 177 of file compute_unittests.cc.

177  {
178  using CS = ThreadgroupSizingTestComputeShader;
179  auto context = GetContext();
180  ASSERT_TRUE(context);
181  ASSERT_TRUE(context->GetCapabilities()->SupportsCompute());
182 
183  using SamplePipelineBuilder = ComputePipelineBuilder<CS>;
184  auto pipeline_desc =
185  SamplePipelineBuilder::MakeDefaultPipelineDescriptor(*context);
186  ASSERT_TRUE(pipeline_desc.has_value());
187  auto compute_pipeline =
188  context->GetPipelineLibrary()->GetPipeline(pipeline_desc).Get();
189  ASSERT_TRUE(compute_pipeline);
190 
191  auto cmd_buffer = context->CreateCommandBuffer();
192  auto pass = cmd_buffer->CreateComputePass();
193  ASSERT_TRUE(pass && pass->IsValid());
194 
195  static constexpr size_t kCount = 2048;
196 
197  pass->SetPipeline(compute_pipeline);
198 
199  auto output_buffer = CreateHostVisibleDeviceBuffer<CS::OutputData<kCount>>(
200  context, "Output Buffer");
201 
202  CS::BindOutputData(*pass, DeviceBuffer::AsBufferView(output_buffer));
203 
204  ASSERT_TRUE(pass->Compute(ISize(kCount, 1)).ok());
205  ASSERT_TRUE(pass->EncodeCommands());
206 
207  fml::AutoResetWaitableEvent latch;
208  ASSERT_TRUE(
209  context->GetCommandQueue()
210  ->Submit({cmd_buffer},
211  [&latch, output_buffer](CommandBuffer::Status status) {
212  EXPECT_EQ(status, CommandBuffer::Status::kCompleted);
213 
214  auto view = DeviceBuffer::AsBufferView(output_buffer);
215  EXPECT_EQ(view.GetRange().length,
216  sizeof(CS::OutputData<kCount>));
217 
218  CS::OutputData<kCount>* output =
219  reinterpret_cast<CS::OutputData<kCount>*>(
220  output_buffer->OnGetContents());
221  EXPECT_TRUE(output);
222  EXPECT_EQ(output->data[kCount - 1], kCount - 1);
223  latch.Signal();
224  })
225  .ok());
226 
227  latch.Wait();
228 }

◆ TEST_P() [294/497]

impeller::testing::TEST_P ( ComputeTest  ,
CanCompute1DimensionalData   
)

Definition at line 377 of file compute_unittests.cc.

377  {
378  using CS = SampleComputeShader;
379  auto context = GetContext();
380  auto host_buffer = HostBuffer::Create(context->GetResourceAllocator(),
381  context->GetIdleWaiter());
382  ASSERT_TRUE(context);
383  ASSERT_TRUE(context->GetCapabilities()->SupportsCompute());
384 
385  using SamplePipelineBuilder = ComputePipelineBuilder<CS>;
386  auto pipeline_desc =
387  SamplePipelineBuilder::MakeDefaultPipelineDescriptor(*context);
388  ASSERT_TRUE(pipeline_desc.has_value());
389  auto compute_pipeline =
390  context->GetPipelineLibrary()->GetPipeline(pipeline_desc).Get();
391  ASSERT_TRUE(compute_pipeline);
392 
393  auto cmd_buffer = context->CreateCommandBuffer();
394  auto pass = cmd_buffer->CreateComputePass();
395  ASSERT_TRUE(pass && pass->IsValid());
396 
397  static constexpr size_t kCount = 5;
398 
399  pass->SetPipeline(compute_pipeline);
400 
401  CS::Info info{.count = kCount};
402  CS::Input0<kCount> input_0;
403  CS::Input1<kCount> input_1;
404  for (size_t i = 0; i < kCount; i++) {
405  input_0.elements[i] = Vector4(2.0 + i, 3.0 + i, 4.0 + i, 5.0 * i);
406  input_1.elements[i] = Vector4(6.0, 7.0, 8.0, 9.0);
407  }
408 
409  input_0.fixed_array[1] = IPoint32(2, 2);
410  input_1.fixed_array[0] = UintPoint32(3, 3);
411  input_0.some_int = 5;
412  input_1.some_struct = CS::SomeStruct{.vf = Point(3, 4), .i = 42};
413 
414  auto output_buffer = CreateHostVisibleDeviceBuffer<CS::Output<kCount>>(
415  context, "Output Buffer");
416 
417  CS::BindInfo(*pass, host_buffer->EmplaceUniform(info));
418  CS::BindInput0(*pass, host_buffer->EmplaceStorageBuffer(input_0));
419  CS::BindInput1(*pass, host_buffer->EmplaceStorageBuffer(input_1));
420  CS::BindOutput(*pass, DeviceBuffer::AsBufferView(output_buffer));
421 
422  ASSERT_TRUE(pass->Compute(ISize(kCount, 1)).ok());
423  ASSERT_TRUE(pass->EncodeCommands());
424 
425  fml::AutoResetWaitableEvent latch;
426  ASSERT_TRUE(
427  context->GetCommandQueue()
428  ->Submit(
429  {cmd_buffer},
430  [&latch, output_buffer, &input_0,
431  &input_1](CommandBuffer::Status status) {
432  EXPECT_EQ(status, CommandBuffer::Status::kCompleted);
433 
434  auto view = DeviceBuffer::AsBufferView(output_buffer);
435  EXPECT_EQ(view.GetRange().length, sizeof(CS::Output<kCount>));
436 
437  CS::Output<kCount>* output =
438  reinterpret_cast<CS::Output<kCount>*>(
439  output_buffer->OnGetContents());
440  EXPECT_TRUE(output);
441  for (size_t i = 0; i < kCount; i++) {
442  Vector4 vector = output->elements[i];
443  Vector4 computed = input_0.elements[i] * input_1.elements[i];
444  EXPECT_EQ(vector,
445  Vector4(computed.x + 2 + input_1.some_struct.i,
446  computed.y + 3 + input_1.some_struct.vf.x,
447  computed.z + 5 + input_1.some_struct.vf.y,
448  computed.w));
449  }
450  latch.Signal();
451  })
452  .ok());
453 
454  latch.Wait();
455 }
TPoint< int32_t > IPoint32
Definition: point.h:329
TPoint< uint32_t > UintPoint32
Definition: point.h:330

References impeller::interop::Create().

◆ TEST_P() [295/497]

impeller::testing::TEST_P ( ComputeTest  ,
CanComputePrefixSum   
)

Definition at line 110 of file compute_unittests.cc.

110  {
111  using CS = PrefixSumTestComputeShader;
112  auto context = GetContext();
113  auto host_buffer = HostBuffer::Create(context->GetResourceAllocator(),
114  context->GetIdleWaiter());
115  ASSERT_TRUE(context);
116  ASSERT_TRUE(context->GetCapabilities()->SupportsCompute());
117 
118  using SamplePipelineBuilder = ComputePipelineBuilder<CS>;
119  auto pipeline_desc =
120  SamplePipelineBuilder::MakeDefaultPipelineDescriptor(*context);
121  ASSERT_TRUE(pipeline_desc.has_value());
122  auto compute_pipeline =
123  context->GetPipelineLibrary()->GetPipeline(pipeline_desc).Get();
124  ASSERT_TRUE(compute_pipeline);
125 
126  auto cmd_buffer = context->CreateCommandBuffer();
127  auto pass = cmd_buffer->CreateComputePass();
128  ASSERT_TRUE(pass && pass->IsValid());
129 
130  static constexpr size_t kCount = 5;
131 
132  pass->SetPipeline(compute_pipeline);
133 
134  CS::InputData<kCount> input_data;
135  input_data.count = kCount;
136  for (size_t i = 0; i < kCount; i++) {
137  input_data.data[i] = 1 + i;
138  }
139 
140  auto output_buffer = CreateHostVisibleDeviceBuffer<CS::OutputData<kCount>>(
141  context, "Output Buffer");
142 
143  CS::BindInputData(*pass, host_buffer->EmplaceStorageBuffer(input_data));
144  CS::BindOutputData(*pass, DeviceBuffer::AsBufferView(output_buffer));
145 
146  ASSERT_TRUE(pass->Compute(ISize(kCount, 1)).ok());
147  ASSERT_TRUE(pass->EncodeCommands());
148 
149  fml::AutoResetWaitableEvent latch;
150  ASSERT_TRUE(
151  context->GetCommandQueue()
152  ->Submit({cmd_buffer},
153  [&latch, output_buffer](CommandBuffer::Status status) {
154  EXPECT_EQ(status, CommandBuffer::Status::kCompleted);
155 
156  auto view = DeviceBuffer::AsBufferView(output_buffer);
157  EXPECT_EQ(view.GetRange().length,
158  sizeof(CS::OutputData<kCount>));
159 
160  CS::OutputData<kCount>* output =
161  reinterpret_cast<CS::OutputData<kCount>*>(
162  output_buffer->OnGetContents());
163  EXPECT_TRUE(output);
164 
165  constexpr uint32_t expected[kCount] = {1, 3, 6, 10, 15};
166  for (size_t i = 0; i < kCount; i++) {
167  auto computed_sum = output->data[i];
168  EXPECT_EQ(computed_sum, expected[i]);
169  }
170  latch.Signal();
171  })
172  .ok());
173 
174  latch.Wait();
175 }

References impeller::DeviceBuffer::AsBufferView(), and impeller::HostBuffer::Create().

◆ TEST_P() [296/497]

impeller::testing::TEST_P ( ComputeTest  ,
CanComputePrefixSumLargeInteractive   
)

Definition at line 230 of file compute_unittests.cc.

230  {
231  using CS = PrefixSumTestComputeShader;
232 
233  auto context = GetContext();
234  auto host_buffer = HostBuffer::Create(context->GetResourceAllocator(),
235  context->GetIdleWaiter());
236 
237  ASSERT_TRUE(context);
238  ASSERT_TRUE(context->GetCapabilities()->SupportsCompute());
239 
240  auto callback = [&](RenderPass& render_pass) -> bool {
241  using SamplePipelineBuilder = ComputePipelineBuilder<CS>;
242  auto pipeline_desc =
243  SamplePipelineBuilder::MakeDefaultPipelineDescriptor(*context);
244  auto compute_pipeline =
245  context->GetPipelineLibrary()->GetPipeline(pipeline_desc).Get();
246 
247  auto cmd_buffer = context->CreateCommandBuffer();
248  auto pass = cmd_buffer->CreateComputePass();
249 
250  static constexpr size_t kCount = 1023;
251 
252  pass->SetPipeline(compute_pipeline);
253 
254  CS::InputData<kCount> input_data;
255  input_data.count = kCount;
256  for (size_t i = 0; i < kCount; i++) {
257  input_data.data[i] = 1 + i;
258  }
259 
260  auto output_buffer = CreateHostVisibleDeviceBuffer<CS::OutputData<kCount>>(
261  context, "Output Buffer");
262 
263  CS::BindInputData(*pass, host_buffer->EmplaceStorageBuffer(input_data));
264  CS::BindOutputData(*pass, DeviceBuffer::AsBufferView(output_buffer));
265 
266  pass->Compute(ISize(kCount, 1));
267  pass->EncodeCommands();
268  host_buffer->Reset();
269  return context->GetCommandQueue()->Submit({cmd_buffer}).ok();
270  };
271  ASSERT_TRUE(OpenPlaygroundHere(callback));
272 }

References impeller::interop::Create().

◆ TEST_P() [297/497]

impeller::testing::TEST_P ( ComputeTest  ,
CanCreateComputePass   
)

Definition at line 30 of file compute_unittests.cc.

30  {
31  using CS = SampleComputeShader;
32  auto context = GetContext();
33  auto host_buffer = HostBuffer::Create(context->GetResourceAllocator(),
34  context->GetIdleWaiter());
35  ASSERT_TRUE(context);
36  ASSERT_TRUE(context->GetCapabilities()->SupportsCompute());
37 
38  using SamplePipelineBuilder = ComputePipelineBuilder<CS>;
39  auto pipeline_desc =
40  SamplePipelineBuilder::MakeDefaultPipelineDescriptor(*context);
41  ASSERT_TRUE(pipeline_desc.has_value());
42  auto compute_pipeline =
43  context->GetPipelineLibrary()->GetPipeline(pipeline_desc).Get();
44  ASSERT_TRUE(compute_pipeline);
45 
46  auto cmd_buffer = context->CreateCommandBuffer();
47  auto pass = cmd_buffer->CreateComputePass();
48  ASSERT_TRUE(pass && pass->IsValid());
49 
50  static constexpr size_t kCount = 5;
51 
52  pass->SetPipeline(compute_pipeline);
53 
54  CS::Info info{.count = kCount};
55  CS::Input0<kCount> input_0;
56  CS::Input1<kCount> input_1;
57  for (size_t i = 0; i < kCount; i++) {
58  input_0.elements[i] = Vector4(2.0 + i, 3.0 + i, 4.0 + i, 5.0 * i);
59  input_1.elements[i] = Vector4(6.0, 7.0, 8.0, 9.0);
60  }
61 
62  input_0.fixed_array[1] = IPoint32(2, 2);
63  input_1.fixed_array[0] = UintPoint32(3, 3);
64  input_0.some_int = 5;
65  input_1.some_struct = CS::SomeStruct{.vf = Point(3, 4), .i = 42};
66 
67  auto output_buffer = CreateHostVisibleDeviceBuffer<CS::Output<kCount>>(
68  context, "Output Buffer");
69 
70  CS::BindInfo(*pass, host_buffer->EmplaceUniform(info));
71  CS::BindInput0(*pass, host_buffer->EmplaceStorageBuffer(input_0));
72  CS::BindInput1(*pass, host_buffer->EmplaceStorageBuffer(input_1));
73  CS::BindOutput(*pass, DeviceBuffer::AsBufferView(output_buffer));
74 
75  ASSERT_TRUE(pass->Compute(ISize(kCount, 1)).ok());
76  ASSERT_TRUE(pass->EncodeCommands());
77 
78  fml::AutoResetWaitableEvent latch;
79  ASSERT_TRUE(
80  context->GetCommandQueue()
81  ->Submit(
82  {cmd_buffer},
83  [&latch, output_buffer, &input_0,
84  &input_1](CommandBuffer::Status status) {
85  EXPECT_EQ(status, CommandBuffer::Status::kCompleted);
86 
87  auto view = DeviceBuffer::AsBufferView(output_buffer);
88  EXPECT_EQ(view.GetRange().length, sizeof(CS::Output<kCount>));
89 
90  CS::Output<kCount>* output =
91  reinterpret_cast<CS::Output<kCount>*>(
92  output_buffer->OnGetContents());
93  EXPECT_TRUE(output);
94  for (size_t i = 0; i < kCount; i++) {
95  Vector4 vector = output->elements[i];
96  Vector4 computed = input_0.elements[i] * input_1.elements[i];
97  EXPECT_EQ(vector,
98  Vector4(computed.x + 2 + input_1.some_struct.i,
99  computed.y + 3 + input_1.some_struct.vf.x,
100  computed.z + 5 + input_1.some_struct.vf.y,
101  computed.w));
102  }
103  latch.Signal();
104  })
105  .ok());
106 
107  latch.Wait();
108 }

References impeller::DeviceBuffer::AsBufferView(), and impeller::HostBuffer::Create().

◆ TEST_P() [298/497]

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() [299/497]

impeller::testing::TEST_P ( ComputeTest  ,
MultiStageInputAndOutput   
)

Definition at line 274 of file compute_unittests.cc.

274  {
275  using CS1 = Stage1ComputeShader;
276  using Stage1PipelineBuilder = ComputePipelineBuilder<CS1>;
277  using CS2 = Stage2ComputeShader;
278  using Stage2PipelineBuilder = ComputePipelineBuilder<CS2>;
279 
280  auto context = GetContext();
281  auto host_buffer = HostBuffer::Create(context->GetResourceAllocator(),
282  context->GetIdleWaiter());
283  ASSERT_TRUE(context);
284  ASSERT_TRUE(context->GetCapabilities()->SupportsCompute());
285 
286  auto pipeline_desc_1 =
287  Stage1PipelineBuilder::MakeDefaultPipelineDescriptor(*context);
288  ASSERT_TRUE(pipeline_desc_1.has_value());
289  auto compute_pipeline_1 =
290  context->GetPipelineLibrary()->GetPipeline(pipeline_desc_1).Get();
291  ASSERT_TRUE(compute_pipeline_1);
292 
293  auto pipeline_desc_2 =
294  Stage2PipelineBuilder::MakeDefaultPipelineDescriptor(*context);
295  ASSERT_TRUE(pipeline_desc_2.has_value());
296  auto compute_pipeline_2 =
297  context->GetPipelineLibrary()->GetPipeline(pipeline_desc_2).Get();
298  ASSERT_TRUE(compute_pipeline_2);
299 
300  auto cmd_buffer = context->CreateCommandBuffer();
301  auto pass = cmd_buffer->CreateComputePass();
302  ASSERT_TRUE(pass && pass->IsValid());
303 
304  static constexpr size_t kCount1 = 5;
305  static constexpr size_t kCount2 = kCount1 * 2;
306 
307  CS1::Input<kCount1> input_1;
308  input_1.count = kCount1;
309  for (size_t i = 0; i < kCount1; i++) {
310  input_1.elements[i] = i;
311  }
312 
313  CS2::Input<kCount2> input_2;
314  input_2.count = kCount2;
315  for (size_t i = 0; i < kCount2; i++) {
316  input_2.elements[i] = i;
317  }
318 
319  auto output_buffer_1 = CreateHostVisibleDeviceBuffer<CS1::Output<kCount2>>(
320  context, "Output Buffer Stage 1");
321  auto output_buffer_2 = CreateHostVisibleDeviceBuffer<CS2::Output<kCount2>>(
322  context, "Output Buffer Stage 2");
323 
324  {
325  pass->SetPipeline(compute_pipeline_1);
326 
327  CS1::BindInput(*pass, host_buffer->EmplaceStorageBuffer(input_1));
328  CS1::BindOutput(*pass, DeviceBuffer::AsBufferView(output_buffer_1));
329 
330  ASSERT_TRUE(pass->Compute(ISize(512, 1)).ok());
331  pass->AddBufferMemoryBarrier();
332  }
333 
334  {
335  pass->SetPipeline(compute_pipeline_2);
336 
337  CS1::BindInput(*pass, DeviceBuffer::AsBufferView(output_buffer_1));
338  CS2::BindOutput(*pass, DeviceBuffer::AsBufferView(output_buffer_2));
339  ASSERT_TRUE(pass->Compute(ISize(512, 1)).ok());
340  }
341 
342  ASSERT_TRUE(pass->EncodeCommands());
343 
344  fml::AutoResetWaitableEvent latch;
345  ASSERT_TRUE(
346  context->GetCommandQueue()
347  ->Submit({cmd_buffer},
348  [&latch, &output_buffer_1,
349  &output_buffer_2](CommandBuffer::Status status) {
350  EXPECT_EQ(status, CommandBuffer::Status::kCompleted);
351 
352  CS1::Output<kCount2>* output_1 =
353  reinterpret_cast<CS1::Output<kCount2>*>(
354  output_buffer_1->OnGetContents());
355  EXPECT_TRUE(output_1);
356  EXPECT_EQ(output_1->count, 10u);
357  EXPECT_THAT(
358  output_1->elements,
359  ::testing::ElementsAre(0, 0, 2, 3, 4, 6, 6, 9, 8, 12));
360 
361  CS2::Output<kCount2>* output_2 =
362  reinterpret_cast<CS2::Output<kCount2>*>(
363  output_buffer_2->OnGetContents());
364  EXPECT_TRUE(output_2);
365  EXPECT_EQ(output_2->count, 10u);
366  EXPECT_THAT(output_2->elements,
367  ::testing::ElementsAre(0, 0, 4, 6, 8, 12, 12,
368  18, 16, 24));
369 
370  latch.Signal();
371  })
372  .ok());
373 
374  latch.Wait();
375 }

References impeller::interop::Create(), and impeller::kCount1.

◆ TEST_P() [300/497]

impeller::testing::TEST_P ( ComputeTest  ,
ReturnsEarlyWhenAnyGridDimensionIsZero   
)

Definition at line 457 of file compute_unittests.cc.

457  {
458  using CS = SampleComputeShader;
459  auto context = GetContext();
460  auto host_buffer = HostBuffer::Create(context->GetResourceAllocator(),
461  context->GetIdleWaiter());
462  ASSERT_TRUE(context);
463  ASSERT_TRUE(context->GetCapabilities()->SupportsCompute());
464 
465  using SamplePipelineBuilder = ComputePipelineBuilder<CS>;
466  auto pipeline_desc =
467  SamplePipelineBuilder::MakeDefaultPipelineDescriptor(*context);
468  ASSERT_TRUE(pipeline_desc.has_value());
469  auto compute_pipeline =
470  context->GetPipelineLibrary()->GetPipeline(pipeline_desc).Get();
471  ASSERT_TRUE(compute_pipeline);
472 
473  auto cmd_buffer = context->CreateCommandBuffer();
474  auto pass = cmd_buffer->CreateComputePass();
475  ASSERT_TRUE(pass && pass->IsValid());
476 
477  static constexpr size_t kCount = 5;
478 
479  pass->SetPipeline(compute_pipeline);
480 
481  CS::Info info{.count = kCount};
482  CS::Input0<kCount> input_0;
483  CS::Input1<kCount> input_1;
484  for (size_t i = 0; i < kCount; i++) {
485  input_0.elements[i] = Vector4(2.0 + i, 3.0 + i, 4.0 + i, 5.0 * i);
486  input_1.elements[i] = Vector4(6.0, 7.0, 8.0, 9.0);
487  }
488 
489  input_0.fixed_array[1] = IPoint32(2, 2);
490  input_1.fixed_array[0] = UintPoint32(3, 3);
491  input_0.some_int = 5;
492  input_1.some_struct = CS::SomeStruct{.vf = Point(3, 4), .i = 42};
493 
494  auto output_buffer = CreateHostVisibleDeviceBuffer<CS::Output<kCount>>(
495  context, "Output Buffer");
496 
497  CS::BindInfo(*pass, host_buffer->EmplaceUniform(info));
498  CS::BindInput0(*pass, host_buffer->EmplaceStorageBuffer(input_0));
499  CS::BindInput1(*pass, host_buffer->EmplaceStorageBuffer(input_1));
500  CS::BindOutput(*pass, DeviceBuffer::AsBufferView(output_buffer));
501 
502  // Intentionally making the grid size zero in one dimension. No GPU will
503  // tolerate this.
504  EXPECT_FALSE(pass->Compute(ISize(0, 1)).ok());
505  pass->EncodeCommands();
506 }

References impeller::interop::Create().

◆ TEST_P() [301/497]

impeller::testing::TEST_P ( DisplayListTest  ,
CanBlendDstOverAndDstCorrectly   
)

Definition at line 1170 of file dl_unittests.cc.

1170  {
1171  flutter::DisplayListBuilder builder;
1172 
1173  {
1174  builder.SaveLayer(nullptr, nullptr);
1175  builder.Translate(100, 100);
1176  flutter::DlPaint paint;
1177  paint.setColor(flutter::DlColor::kRed());
1178  builder.DrawRect(SkRect::MakeSize({200, 200}), paint);
1179  paint.setColor(flutter::DlColor::kBlue().withAlpha(127));
1180  paint.setBlendMode(flutter::DlBlendMode::kSrcOver);
1181  builder.DrawRect(SkRect::MakeSize({200, 200}), paint);
1182  builder.Restore();
1183  }
1184  {
1185  builder.SaveLayer(nullptr, nullptr);
1186  builder.Translate(300, 100);
1187  flutter::DlPaint paint;
1188  paint.setColor(flutter::DlColor::kBlue().withAlpha(127));
1189  builder.DrawRect(SkRect::MakeSize({200, 200}), paint);
1190  paint.setColor(flutter::DlColor::kRed());
1191  paint.setBlendMode(flutter::DlBlendMode::kDstOver);
1192  builder.DrawRect(SkRect::MakeSize({200, 200}), paint);
1193  builder.Restore();
1194  }
1195  {
1196  builder.SaveLayer(nullptr, nullptr);
1197  builder.Translate(100, 300);
1198  flutter::DlPaint paint;
1199  paint.setColor(flutter::DlColor::kRed());
1200  builder.DrawRect(SkRect::MakeSize({200, 200}), paint);
1201  paint.setColor(flutter::DlColor::kBlue().withAlpha(127));
1202  paint.setBlendMode(flutter::DlBlendMode::kSrc);
1203  builder.DrawRect(SkRect::MakeSize({200, 200}), paint);
1204  builder.Restore();
1205  }
1206  {
1207  builder.SaveLayer(nullptr, nullptr);
1208  builder.Translate(300, 300);
1209  flutter::DlPaint paint;
1210  paint.setColor(flutter::DlColor::kBlue().withAlpha(127));
1211  builder.DrawRect(SkRect::MakeSize({200, 200}), paint);
1212  paint.setColor(flutter::DlColor::kRed());
1213  paint.setBlendMode(flutter::DlBlendMode::kDst);
1214  builder.DrawRect(SkRect::MakeSize({200, 200}), paint);
1215  builder.Restore();
1216  }
1217 
1218  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1219 }

◆ TEST_P() [302/497]

impeller::testing::TEST_P ( DisplayListTest  ,
CanClampTheResultingColorOfColorMatrixFilter   
)

Definition at line 614 of file dl_unittests.cc.

614  {
615  auto texture = CreateTextureForFixture("boston.jpg");
616  const float inner_color_matrix[20] = {
617  1, 0, 0, 0, 0, //
618  0, 1, 0, 0, 0, //
619  0, 0, 1, 0, 0, //
620  0, 0, 0, 2, 0, //
621  };
622  const float outer_color_matrix[20] = {
623  1, 0, 0, 0, 0, //
624  0, 1, 0, 0, 0, //
625  0, 0, 1, 0, 0, //
626  0, 0, 0, 0.5, 0, //
627  };
628  auto inner_color_filter =
629  flutter::DlColorFilter::MakeMatrix(inner_color_matrix);
630  auto outer_color_filter =
631  flutter::DlColorFilter::MakeMatrix(outer_color_matrix);
632  auto inner = flutter::DlImageFilter::MakeColorFilter(inner_color_filter);
633  auto outer = flutter::DlImageFilter::MakeColorFilter(outer_color_filter);
634  auto compose = std::make_shared<flutter::DlComposeImageFilter>(outer, inner);
635 
636  flutter::DisplayListBuilder builder;
637  flutter::DlPaint paint;
638  paint.setImageFilter(compose.get());
639  builder.DrawImage(DlImageImpeller::Make(texture), SkPoint::Make(100, 100),
640  flutter::DlImageSampling::kNearestNeighbor, &paint);
641  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
642 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [303/497]

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 }

◆ TEST_P() [304/497]

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(), scale, stroke_width, and impeller::Color::White().

◆ TEST_P() [305/497]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawBackdropFilter   
)

Definition at line 644 of file dl_unittests.cc.

644  {
645  auto texture = CreateTextureForFixture("embarcadero.jpg");
646 
647  auto callback = [&]() {
648  static float sigma[] = {10, 10};
649  static float ctm_scale = 1;
650  static bool use_bounds = true;
651  static bool draw_circle = true;
652  static bool add_clip = true;
653 
654  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
655  ImGui::SliderFloat2("Sigma", sigma, 0, 100);
656  ImGui::SliderFloat("Scale", &ctm_scale, 0, 10);
657  ImGui::NewLine();
658  ImGui::TextWrapped(
659  "If everything is working correctly, none of the options below should "
660  "impact the filter's appearance.");
661  ImGui::Checkbox("Use SaveLayer bounds", &use_bounds);
662  ImGui::Checkbox("Draw child element", &draw_circle);
663  ImGui::Checkbox("Add pre-clip", &add_clip);
664  ImGui::End();
665 
666  flutter::DisplayListBuilder builder;
667 
668  Vector2 scale = ctm_scale * GetContentScale();
669  builder.Scale(scale.x, scale.y);
670 
671  auto filter = flutter::DlBlurImageFilter(sigma[0], sigma[1],
672  flutter::DlTileMode::kClamp);
673 
674  std::optional<SkRect> bounds;
675  if (use_bounds) {
676  static PlaygroundPoint point_a(Point(350, 150), 20, Color::White());
677  static PlaygroundPoint point_b(Point(800, 600), 20, Color::White());
678  auto [p1, p2] = DrawPlaygroundLine(point_a, point_b);
679  bounds = SkRect::MakeLTRB(p1.x, p1.y, p2.x, p2.y);
680  }
681 
682  // Insert a clip to test that the backdrop filter handles stencil depths > 0
683  // correctly.
684  if (add_clip) {
685  builder.ClipRect(SkRect::MakeLTRB(0, 0, 99999, 99999),
686  flutter::DlCanvas::ClipOp::kIntersect, true);
687  }
688 
689  builder.DrawImage(DlImageImpeller::Make(texture), SkPoint::Make(200, 200),
690  flutter::DlImageSampling::kNearestNeighbor, nullptr);
691  builder.SaveLayer(bounds.has_value() ? &bounds.value() : nullptr, nullptr,
692  &filter);
693 
694  if (draw_circle) {
695  static PlaygroundPoint center_point(Point(500, 400), 20, Color::Red());
696  auto circle_center = DrawPlaygroundPoint(center_point);
697 
698  flutter::DlPaint paint;
699  paint.setDrawStyle(flutter::DlDrawStyle::kStroke);
700  paint.setStrokeCap(flutter::DlStrokeCap::kButt);
701  paint.setStrokeJoin(flutter::DlStrokeJoin::kBevel);
702  paint.setStrokeWidth(10);
703  paint.setColor(flutter::DlColor::kRed().withAlpha(100));
704  builder.DrawCircle(SkPoint{circle_center.x, circle_center.y}, 100, paint);
705  }
706 
707  return builder.Build();
708  };
709 
710  ASSERT_TRUE(OpenPlaygroundHere(callback));
711 }

References impeller::DrawPlaygroundLine(), impeller::DrawPlaygroundPoint(), impeller::DlImageImpeller::Make(), impeller::Color::Red(), scale, and impeller::Color::White().

◆ TEST_P() [306/497]

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 }

◆ TEST_P() [307/497]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawCorrectlyWithColorFilterAndImageFilter   
)

Definition at line 1221 of file dl_unittests.cc.

1221  {
1222  flutter::DisplayListBuilder builder;
1223  const float green_color_matrix[20] = {
1224  0, 0, 0, 0, 0, //
1225  0, 0, 0, 0, 1, //
1226  0, 0, 0, 0, 0, //
1227  0, 0, 0, 1, 0, //
1228  };
1229  const float blue_color_matrix[20] = {
1230  0, 0, 0, 0, 0, //
1231  0, 0, 0, 0, 0, //
1232  0, 0, 0, 0, 1, //
1233  0, 0, 0, 1, 0, //
1234  };
1235  auto green_color_filter =
1236  flutter::DlColorFilter::MakeMatrix(green_color_matrix);
1237  auto blue_color_filter =
1238  flutter::DlColorFilter::MakeMatrix(blue_color_matrix);
1239  auto blue_image_filter =
1240  flutter::DlImageFilter::MakeColorFilter(blue_color_filter);
1241 
1242  flutter::DlPaint paint;
1243  paint.setColor(flutter::DlColor::kRed());
1244  paint.setColorFilter(green_color_filter);
1245  paint.setImageFilter(blue_image_filter);
1246  builder.DrawRect(SkRect::MakeLTRB(100, 100, 500, 500), paint);
1247  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1248 }

◆ TEST_P() [308/497]

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() [309/497]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawNinePatchImage   
)

Definition at line 713 of file dl_unittests.cc.

713  {
714  // Image is drawn with corners to scale and center pieces stretched to fit.
715  auto texture = CreateTextureForFixture("embarcadero.jpg");
716  flutter::DisplayListBuilder builder;
717  auto size = texture->GetSize();
718  builder.DrawImageNine(
719  DlImageImpeller::Make(texture),
720  SkIRect::MakeLTRB(size.width / 4, size.height / 4, size.width * 3 / 4,
721  size.height * 3 / 4),
722  SkRect::MakeLTRB(0, 0, size.width * 2, size.height * 2),
723  flutter::DlFilterMode::kNearest, nullptr);
724  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
725 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [310/497]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawNinePatchImageCenterBiggerThanDest   
)

Definition at line 759 of file dl_unittests.cc.

759  {
760  // Edge case, the width and height of the corners does not leave any
761  // room for the center slices. Only the corners are displayed.
762  auto texture = CreateTextureForFixture("embarcadero.jpg");
763  flutter::DisplayListBuilder builder;
764  auto size = texture->GetSize();
765  builder.DrawImageNine(
766  DlImageImpeller::Make(texture),
767  SkIRect::MakeLTRB(size.width / 4, size.height / 4, size.width * 3 / 4,
768  size.height * 3 / 4),
769  SkRect::MakeLTRB(0, 0, size.width / 2, size.height / 2),
770  flutter::DlFilterMode::kNearest, nullptr);
771  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
772 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [311/497]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawNinePatchImageCenterHeightBiggerThanDest   
)

Definition at line 743 of file dl_unittests.cc.

743  {
744  // Edge case, the height of the corners does not leave any room for the
745  // center slice. The center (across the horizontal axis) is folded out of the
746  // resulting image.
747  auto texture = CreateTextureForFixture("embarcadero.jpg");
748  flutter::DisplayListBuilder builder;
749  auto size = texture->GetSize();
750  builder.DrawImageNine(
751  DlImageImpeller::Make(texture),
752  SkIRect::MakeLTRB(size.width / 4, size.height / 4, size.width * 3 / 4,
753  size.height * 3 / 4),
754  SkRect::MakeLTRB(0, 0, size.width, size.height / 2),
755  flutter::DlFilterMode::kNearest, nullptr);
756  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
757 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [312/497]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawNinePatchImageCenterWidthBiggerThanDest   
)

Definition at line 727 of file dl_unittests.cc.

727  {
728  // Edge case, the width of the corners does not leave any room for the
729  // center slice. The center (across the vertical axis) is folded out of the
730  // resulting image.
731  auto texture = CreateTextureForFixture("embarcadero.jpg");
732  flutter::DisplayListBuilder builder;
733  auto size = texture->GetSize();
734  builder.DrawImageNine(
735  DlImageImpeller::Make(texture),
736  SkIRect::MakeLTRB(size.width / 4, size.height / 4, size.width * 3 / 4,
737  size.height * 3 / 4),
738  SkRect::MakeLTRB(0, 0, size.width / 2, size.height),
739  flutter::DlFilterMode::kNearest, nullptr);
740  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
741 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [313/497]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawNinePatchImageCornersScaledDown   
)

Definition at line 774 of file dl_unittests.cc.

774  {
775  // Edge case, there is not enough room for the corners to be drawn
776  // without scaling them down.
777  auto texture = CreateTextureForFixture("embarcadero.jpg");
778  flutter::DisplayListBuilder builder;
779  auto size = texture->GetSize();
780  builder.DrawImageNine(
781  DlImageImpeller::Make(texture),
782  SkIRect::MakeLTRB(size.width / 4, size.height / 4, size.width * 3 / 4,
783  size.height * 3 / 4),
784  SkRect::MakeLTRB(0, 0, size.width / 4, size.height / 4),
785  flutter::DlFilterMode::kNearest, nullptr);
786  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
787 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [314/497]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawPaintWithColorSource   
)

Definition at line 1118 of file dl_unittests.cc.

1118  {
1119  const flutter::DlColor colors[2] = {
1120  flutter::DlColor(0xFFF44336),
1121  flutter::DlColor(0xFF2196F3),
1122  };
1123  const float stops[2] = {0.0, 1.0};
1124  flutter::DlPaint paint;
1125  flutter::DisplayListBuilder builder;
1126  auto clip_bounds = SkRect::MakeWH(300.0, 300.0);
1127  builder.Save();
1128  builder.Translate(100, 100);
1129  builder.ClipRect(clip_bounds, flutter::DlCanvas::ClipOp::kIntersect, false);
1130  auto linear =
1131  flutter::DlColorSource::MakeLinear({0.0, 0.0}, {100.0, 100.0}, 2, colors,
1132  stops, flutter::DlTileMode::kRepeat);
1133  paint.setColorSource(linear);
1134  builder.DrawPaint(paint);
1135  builder.Restore();
1136 
1137  builder.Save();
1138  builder.Translate(500, 100);
1139  builder.ClipRect(clip_bounds, flutter::DlCanvas::ClipOp::kIntersect, false);
1140  auto radial = flutter::DlColorSource::MakeRadial(
1141  {100.0, 100.0}, 100.0, 2, colors, stops, flutter::DlTileMode::kRepeat);
1142  paint.setColorSource(radial);
1143  builder.DrawPaint(paint);
1144  builder.Restore();
1145 
1146  builder.Save();
1147  builder.Translate(100, 500);
1148  builder.ClipRect(clip_bounds, flutter::DlCanvas::ClipOp::kIntersect, false);
1149  auto sweep =
1150  flutter::DlColorSource::MakeSweep({100.0, 100.0}, 180.0, 270.0, 2, colors,
1151  stops, flutter::DlTileMode::kRepeat);
1152  paint.setColorSource(sweep);
1153  builder.DrawPaint(paint);
1154  builder.Restore();
1155 
1156  builder.Save();
1157  builder.Translate(500, 500);
1158  builder.ClipRect(clip_bounds, flutter::DlCanvas::ClipOp::kIntersect, false);
1159  auto texture = CreateTextureForFixture("table_mountain_nx.png");
1160  auto image = flutter::DlColorSource::MakeImage(DlImageImpeller::Make(texture),
1161  flutter::DlTileMode::kRepeat,
1162  flutter::DlTileMode::kRepeat);
1163  paint.setColorSource(image);
1164  builder.DrawPaint(paint);
1165  builder.Restore();
1166 
1167  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1168 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [315/497]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawPoints   
)

Definition at line 801 of file dl_unittests.cc.

801  {
802  flutter::DisplayListBuilder builder;
803  SkPoint points[7] = {
804  {0, 0}, //
805  {100, 100}, //
806  {100, 0}, //
807  {0, 100}, //
808  {0, 0}, //
809  {48, 48}, //
810  {52, 52}, //
811  };
812  std::vector<flutter::DlStrokeCap> caps = {
813  flutter::DlStrokeCap::kButt,
814  flutter::DlStrokeCap::kRound,
815  flutter::DlStrokeCap::kSquare,
816  };
817  flutter::DlPaint paint =
818  flutter::DlPaint() //
819  .setColor(flutter::DlColor::kYellow().withAlpha(127)) //
820  .setStrokeWidth(20);
821  builder.Translate(50, 50);
822  for (auto cap : caps) {
823  paint.setStrokeCap(cap);
824  builder.Save();
825  builder.DrawPoints(flutter::DlCanvas::PointMode::kPoints, 7, points, paint);
826  builder.Translate(150, 0);
827  builder.DrawPoints(flutter::DlCanvas::PointMode::kLines, 5, points, paint);
828  builder.Translate(150, 0);
829  builder.DrawPoints(flutter::DlCanvas::PointMode::kPolygon, 5, points,
830  paint);
831  builder.Restore();
832  builder.Translate(0, 150);
833  }
834  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
835 }

◆ TEST_P() [316/497]

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() [317/497]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawRectWithLinearToSrgbColorFilter   
)

Definition at line 1104 of file dl_unittests.cc.

1104  {
1105  flutter::DlPaint paint;
1106  paint.setColor(flutter::DlColor(0xFF2196F3).withAlpha(128));
1107  flutter::DisplayListBuilder builder;
1108  paint.setColorFilter(flutter::DlColorFilter::MakeLinearToSrgbGamma());
1109  builder.DrawRect(SkRect::MakeXYWH(0, 0, 200, 200), paint);
1110  builder.Translate(0, 200);
1111 
1112  paint.setColorFilter(flutter::DlColorFilter::MakeSrgbToLinearGamma());
1113  builder.DrawRect(SkRect::MakeXYWH(0, 0, 200, 200), paint);
1114 
1115  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1116 }

◆ TEST_P() [318/497]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawShadow   
)

Definition at line 860 of file dl_unittests.cc.

860  {
861  flutter::DisplayListBuilder builder;
862  flutter::DlPaint paint;
863 
864  auto content_scale = GetContentScale() * 0.8;
865  builder.Scale(content_scale.x, content_scale.y);
866 
867  constexpr size_t star_spikes = 5;
868  constexpr SkScalar half_spike_rotation = kPi / star_spikes;
869  constexpr SkScalar radius = 40;
870  constexpr SkScalar spike_size = 10;
871  constexpr SkScalar outer_radius = radius + spike_size;
872  constexpr SkScalar inner_radius = radius - spike_size;
873  std::array<SkPoint, star_spikes * 2> star;
874  for (size_t i = 0; i < star_spikes; i++) {
875  const SkScalar rotation = half_spike_rotation * i * 2;
876  star[i * 2] = SkPoint::Make(50 + std::sin(rotation) * outer_radius,
877  50 - std::cos(rotation) * outer_radius);
878  star[i * 2 + 1] = SkPoint::Make(
879  50 + std::sin(rotation + half_spike_rotation) * inner_radius,
880  50 - std::cos(rotation + half_spike_rotation) * inner_radius);
881  }
882 
883  std::array<SkPath, 4> paths = {
884  SkPath{}.addRect(SkRect::MakeXYWH(0, 0, 200, 100)),
885  SkPath{}.addRRect(
886  SkRRect::MakeRectXY(SkRect::MakeXYWH(20, 0, 200, 100), 30, 30)),
887  SkPath{}.addCircle(100, 50, 50),
888  SkPath{}.addPoly(star.data(), star.size(), true),
889  };
890  paint.setColor(flutter::DlColor::kWhite());
891  builder.DrawPaint(paint);
892  paint.setColor(flutter::DlColor::kCyan());
893  builder.Translate(100, 50);
894  for (size_t x = 0; x < paths.size(); x++) {
895  builder.Save();
896  for (size_t y = 0; y < 6; y++) {
897  builder.DrawShadow(paths[x], flutter::DlColor::kBlack(), 3 + y * 8, false,
898  1);
899  builder.DrawPath(paths[x], paint);
900  builder.Translate(0, 150);
901  }
902  builder.Restore();
903  builder.Translate(250, 0);
904  }
905 
906  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
907 }

References impeller::kPi, and x.

◆ TEST_P() [319/497]

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 }

◆ TEST_P() [320/497]

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() [321/497]

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 }

◆ TEST_P() [322/497]

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() [323/497]

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::DlColorFilter::MakeBlend(
526  flutter::DlColor::kYellow(), 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::DlColorFilter::MakeBlend(
535  flutter::DlColor::kRed(), 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().

◆ TEST_P() [324/497]

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 = flutter::DlColorFilter::MakeMatrix(invert_color_matrix);
556  auto image_filter = flutter::DlImageFilter::MakeColorFilter(color_filter);
557 
558  paint.setImageFilter(image_filter);
559  builder.DrawImage(DlImageImpeller::Make(texture), SkPoint::Make(100, 100),
560  flutter::DlImageSampling::kNearestNeighbor, &paint);
561 
562  builder.Translate(0, 700);
563  paint.setColorFilter(color_filter);
564  builder.DrawImage(DlImageImpeller::Make(texture), SkPoint::Make(100, 100),
565  flutter::DlImageSampling::kNearestNeighbor, &paint);
566  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
567 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [325/497]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawWithComposeImageFilter   
)

Definition at line 594 of file dl_unittests.cc.

594  {
595  auto texture = CreateTextureForFixture("boston.jpg");
596  flutter::DisplayListBuilder builder;
597  flutter::DlPaint paint;
598 
599  auto dilate = std::make_shared<flutter::DlDilateImageFilter>(10.0, 10.0);
600  auto erode = std::make_shared<flutter::DlErodeImageFilter>(10.0, 10.0);
601  auto open = std::make_shared<flutter::DlComposeImageFilter>(dilate, erode);
602  auto close = std::make_shared<flutter::DlComposeImageFilter>(erode, dilate);
603 
604  paint.setImageFilter(open.get());
605  builder.DrawImage(DlImageImpeller::Make(texture), SkPoint::Make(100, 100),
606  flutter::DlImageSampling::kNearestNeighbor, &paint);
607  builder.Translate(0, 700);
608  paint.setImageFilter(close.get());
609  builder.DrawImage(DlImageImpeller::Make(texture), SkPoint::Make(100, 100),
610  flutter::DlImageSampling::kNearestNeighbor, &paint);
611  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
612 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [326/497]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawWithImageBlurFilter   
)

Definition at line 569 of file dl_unittests.cc.

569  {
570  auto texture = CreateTextureForFixture("embarcadero.jpg");
571 
572  auto callback = [&]() {
573  static float sigma[] = {10, 10};
574 
575  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
576  ImGui::SliderFloat2("Sigma", sigma, 0, 100);
577  ImGui::End();
578 
579  flutter::DisplayListBuilder builder;
580  flutter::DlPaint paint;
581 
582  auto filter = flutter::DlBlurImageFilter(sigma[0], sigma[1],
583  flutter::DlTileMode::kClamp);
584  paint.setImageFilter(&filter);
585  builder.DrawImage(DlImageImpeller::Make(texture), SkPoint::Make(200, 200),
586  flutter::DlImageSampling::kNearestNeighbor, &paint);
587 
588  return builder.Build();
589  };
590 
591  ASSERT_TRUE(OpenPlaygroundHere(callback));
592 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [327/497]

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().

◆ TEST_P() [328/497]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawWithMatrixFilter   
)

Definition at line 943 of file dl_unittests.cc.

943  {
944  auto boston = CreateTextureForFixture("boston.jpg");
945 
946  auto callback = [&]() {
947  static int selected_matrix_type = 0;
948  const char* matrix_type_names[] = {"Matrix", "Local Matrix"};
949 
950  static float ctm_translation[2] = {200, 200};
951  static float ctm_scale[2] = {0.65, 0.65};
952  static float ctm_skew[2] = {0, 0};
953 
954  static bool enable = true;
955  static float translation[2] = {100, 100};
956  static float scale[2] = {0.8, 0.8};
957  static float skew[2] = {0.2, 0.2};
958 
959  static bool enable_savelayer = true;
960 
961  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
962  {
963  ImGui::Combo("Filter type", &selected_matrix_type, matrix_type_names,
964  sizeof(matrix_type_names) / sizeof(char*));
965 
966  ImGui::TextWrapped("Current Transform");
967  ImGui::SliderFloat2("CTM Translation", ctm_translation, 0, 1000);
968  ImGui::SliderFloat2("CTM Scale", ctm_scale, 0, 3);
969  ImGui::SliderFloat2("CTM Skew", ctm_skew, -3, 3);
970 
971  ImGui::TextWrapped(
972  "MatrixFilter and LocalMatrixFilter modify the CTM in the same way. "
973  "The only difference is that MatrixFilter doesn't affect the effect "
974  "transform, whereas LocalMatrixFilter does.");
975  // Note: See this behavior in:
976  // https://fiddle.skia.org/c/6cbb551ab36d06f163db8693972be954
977  ImGui::Checkbox("Enable", &enable);
978  ImGui::SliderFloat2("Filter Translation", translation, 0, 1000);
979  ImGui::SliderFloat2("Filter Scale", scale, 0, 3);
980  ImGui::SliderFloat2("Filter Skew", skew, -3, 3);
981 
982  ImGui::TextWrapped(
983  "Rendering the filtered image within a layer can expose bounds "
984  "issues. If the rendered image gets cut off when this setting is "
985  "enabled, there's a coverage bug in the filter.");
986  ImGui::Checkbox("Render in layer", &enable_savelayer);
987  }
988  ImGui::End();
989 
990  flutter::DisplayListBuilder builder;
991  flutter::DlPaint paint;
992 
993  if (enable_savelayer) {
994  builder.SaveLayer(nullptr, nullptr);
995  }
996  {
997  auto content_scale = GetContentScale();
998  builder.Scale(content_scale.x, content_scale.y);
999 
1000  // Set the current transform
1001  auto ctm_matrix =
1002  SkMatrix::MakeAll(ctm_scale[0], ctm_skew[0], ctm_translation[0], //
1003  ctm_skew[1], ctm_scale[1], ctm_translation[1], //
1004  0, 0, 1);
1005  builder.Transform(ctm_matrix);
1006 
1007  // Set the matrix filter
1008  auto filter_matrix =
1009  Matrix::MakeRow(scale[0], skew[0], 0.0f, translation[0], //
1010  skew[1], scale[1], 0.0f, translation[1], //
1011  0.0f, 0.0f, 1.0f, 0.0f, //
1012  0.0f, 0.0f, 0.0f, 1.0f);
1013 
1014  if (enable) {
1015  switch (selected_matrix_type) {
1016  case 0: {
1017  auto filter = flutter::DlMatrixImageFilter(
1018  filter_matrix, flutter::DlImageSampling::kLinear);
1019  paint.setImageFilter(&filter);
1020  break;
1021  }
1022  case 1: {
1023  auto internal_filter =
1024  flutter::DlBlurImageFilter(10, 10, flutter::DlTileMode::kDecal)
1025  .shared();
1026  auto filter = flutter::DlLocalMatrixImageFilter(filter_matrix,
1027  internal_filter);
1028  paint.setImageFilter(&filter);
1029  break;
1030  }
1031  }
1032  }
1033 
1034  builder.DrawImage(DlImageImpeller::Make(boston), SkPoint{},
1035  flutter::DlImageSampling::kLinear, &paint);
1036  }
1037  if (enable_savelayer) {
1038  builder.Restore();
1039  }
1040 
1041  return builder.Build();
1042  };
1043 
1044  ASSERT_TRUE(OpenPlaygroundHere(callback));
1045 }

References impeller::DlImageImpeller::Make(), impeller::Matrix::MakeRow(), and scale.

◆ TEST_P() [329/497]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawWithMatrixFilterWhenSavingLayer   
)

Definition at line 1047 of file dl_unittests.cc.

1047  {
1048  auto callback = [&]() {
1049  static float translation[2] = {0, 0};
1050  static bool enable_save_layer = true;
1051 
1052  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
1053  ImGui::SliderFloat2("Translation", translation, -130, 130);
1054  ImGui::Checkbox("Enable save layer", &enable_save_layer);
1055  ImGui::End();
1056 
1057  flutter::DisplayListBuilder builder;
1058  builder.Save();
1059  builder.Scale(2.0, 2.0);
1060  flutter::DlPaint paint;
1061  paint.setColor(flutter::DlColor::kYellow());
1062  builder.DrawRect(SkRect::MakeWH(300, 300), paint);
1063  paint.setStrokeWidth(1.0);
1064  paint.setDrawStyle(flutter::DlDrawStyle::kStroke);
1065  paint.setColor(flutter::DlColor::kBlack().withAlpha(0x80));
1066  builder.DrawLine(SkPoint::Make(150, 0), SkPoint::Make(150, 300), paint);
1067  builder.DrawLine(SkPoint::Make(0, 150), SkPoint::Make(300, 150), paint);
1068 
1069  flutter::DlPaint save_paint;
1070  SkRect bounds = SkRect::MakeXYWH(100, 100, 100, 100);
1071  Matrix translate_matrix =
1072  Matrix::MakeTranslation({translation[0], translation[1]});
1073  if (enable_save_layer) {
1074  auto filter = flutter::DlMatrixImageFilter(
1075  translate_matrix, flutter::DlImageSampling::kNearestNeighbor);
1076  save_paint.setImageFilter(filter.shared());
1077  builder.SaveLayer(&bounds, &save_paint);
1078  } else {
1079  builder.Save();
1080  builder.Transform(translate_matrix);
1081  }
1082 
1083  Matrix filter_matrix;
1084  filter_matrix.Translate({150, 150});
1085  filter_matrix.Scale({0.2f, 0.2f});
1086  filter_matrix.Translate({-150, -150});
1087  auto filter = flutter::DlMatrixImageFilter(
1088  filter_matrix, flutter::DlImageSampling::kNearestNeighbor);
1089 
1090  save_paint.setImageFilter(filter.shared());
1091 
1092  builder.SaveLayer(&bounds, &save_paint);
1093  flutter::DlPaint paint2;
1094  paint2.setColor(flutter::DlColor::kBlue());
1095  builder.DrawRect(bounds, paint2);
1096  builder.Restore();
1097  builder.Restore();
1098  return builder.Build();
1099  };
1100 
1101  ASSERT_TRUE(OpenPlaygroundHere(callback));
1102 }

References impeller::Matrix::MakeTranslation(), impeller::Matrix::Scale(), and impeller::Matrix::Translate().

◆ TEST_P() [330/497]

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 }

◆ TEST_P() [331/497]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawZeroLengthLine   
)

Definition at line 837 of file dl_unittests.cc.

837  {
838  flutter::DisplayListBuilder builder;
839  std::vector<flutter::DlStrokeCap> caps = {
840  flutter::DlStrokeCap::kButt,
841  flutter::DlStrokeCap::kRound,
842  flutter::DlStrokeCap::kSquare,
843  };
844  flutter::DlPaint paint =
845  flutter::DlPaint() //
846  .setColor(flutter::DlColor::kYellow().withAlpha(127)) //
847  .setDrawStyle(flutter::DlDrawStyle::kStroke) //
848  .setStrokeCap(flutter::DlStrokeCap::kButt) //
849  .setStrokeWidth(20);
850  SkPath path = SkPath().addPoly({{150, 50}, {150, 50}}, false);
851  for (auto cap : caps) {
852  paint.setStrokeCap(cap);
853  builder.DrawLine(SkPoint{50, 50}, SkPoint{50, 50}, paint);
854  builder.DrawPath(path, paint);
855  builder.Translate(0, 150);
856  }
857  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
858 }

◆ TEST_P() [332/497]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawZeroWidthLine   
)

Definition at line 909 of file dl_unittests.cc.

909  {
910  flutter::DisplayListBuilder builder;
911  std::vector<flutter::DlStrokeCap> caps = {
912  flutter::DlStrokeCap::kButt,
913  flutter::DlStrokeCap::kRound,
914  flutter::DlStrokeCap::kSquare,
915  };
916  flutter::DlPaint paint = //
917  flutter::DlPaint() //
918  .setColor(flutter::DlColor::kWhite()) //
919  .setDrawStyle(flutter::DlDrawStyle::kStroke) //
920  .setStrokeWidth(0);
921  flutter::DlPaint outline_paint = //
922  flutter::DlPaint() //
923  .setColor(flutter::DlColor::kYellow()) //
924  .setDrawStyle(flutter::DlDrawStyle::kStroke) //
925  .setStrokeCap(flutter::DlStrokeCap::kSquare) //
926  .setStrokeWidth(1);
927  SkPath path = SkPath().addPoly({{150, 50}, {160, 50}}, false);
928  for (auto cap : caps) {
929  paint.setStrokeCap(cap);
930  builder.DrawLine(SkPoint{50, 50}, SkPoint{60, 50}, paint);
931  builder.DrawRect(SkRect{45, 45, 65, 55}, outline_paint);
932  builder.DrawLine(SkPoint{100, 50}, SkPoint{100, 50}, paint);
933  if (cap != flutter::DlStrokeCap::kButt) {
934  builder.DrawRect(SkRect{95, 45, 105, 55}, outline_paint);
935  }
936  builder.DrawPath(path, paint);
937  builder.DrawRect(path.getBounds().makeOutset(5, 5), outline_paint);
938  builder.Translate(0, 150);
939  }
940  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
941 }

◆ TEST_P() [333/497]

impeller::testing::TEST_P ( DisplayListTest  ,
ClipDrawRRectWithNonCircularRadii   
)

Definition at line 1336 of file dl_unittests.cc.

1336  {
1337  flutter::DisplayListBuilder builder;
1338 
1339  flutter::DlPaint fill_paint = //
1340  flutter::DlPaint() //
1341  .setColor(flutter::DlColor::kBlue()) //
1342  .setDrawStyle(flutter::DlDrawStyle::kFill) //
1343  .setStrokeWidth(10);
1344  flutter::DlPaint stroke_paint = //
1345  flutter::DlPaint() //
1346  .setColor(flutter::DlColor::kGreen()) //
1347  .setDrawStyle(flutter::DlDrawStyle::kStroke) //
1348  .setStrokeWidth(10);
1349 
1350  builder.DrawRRect(
1351  SkRRect::MakeRectXY(SkRect::MakeXYWH(500, 100, 300, 300), 120, 40),
1352  fill_paint);
1353  builder.DrawRRect(
1354  SkRRect::MakeRectXY(SkRect::MakeXYWH(500, 100, 300, 300), 120, 40),
1355  stroke_paint);
1356 
1357  builder.DrawRRect(
1358  SkRRect::MakeRectXY(SkRect::MakeXYWH(100, 500, 300, 300), 40, 120),
1359  fill_paint);
1360  builder.DrawRRect(
1361  SkRRect::MakeRectXY(SkRect::MakeXYWH(100, 500, 300, 300), 40, 120),
1362  stroke_paint);
1363 
1364  flutter::DlPaint reference_paint = //
1365  flutter::DlPaint() //
1366  .setColor(flutter::DlColor::kMidGrey()) //
1367  .setDrawStyle(flutter::DlDrawStyle::kFill) //
1368  .setStrokeWidth(10);
1369 
1370  builder.DrawRRect(
1371  SkRRect::MakeRectXY(SkRect::MakeXYWH(500, 500, 300, 300), 40, 40),
1372  reference_paint);
1373  builder.DrawRRect(
1374  SkRRect::MakeRectXY(SkRect::MakeXYWH(100, 100, 300, 300), 120, 120),
1375  reference_paint);
1376 
1377  flutter::DlPaint clip_fill_paint = //
1378  flutter::DlPaint() //
1379  .setColor(flutter::DlColor::kCyan()) //
1380  .setDrawStyle(flutter::DlDrawStyle::kFill) //
1381  .setStrokeWidth(10);
1382 
1383  builder.Save();
1384  builder.ClipRRect(
1385  SkRRect::MakeRectXY(SkRect::MakeXYWH(900, 100, 300, 300), 120, 40));
1386  builder.DrawPaint(clip_fill_paint);
1387  builder.Restore();
1388 
1389  builder.Save();
1390  builder.ClipRRect(
1391  SkRRect::MakeRectXY(SkRect::MakeXYWH(100, 900, 300, 300), 40, 120));
1392  builder.DrawPaint(clip_fill_paint);
1393  builder.Restore();
1394 
1395  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1396 }

◆ TEST_P() [334/497]

impeller::testing::TEST_P ( DisplayListTest  ,
DrawMaskBlursThatMightUseSaveLayers   
)

Definition at line 1512 of file dl_unittests.cc.

1512  {
1513  flutter::DisplayListBuilder builder;
1514  builder.DrawColor(flutter::DlColor::kWhite(), flutter::DlBlendMode::kSrc);
1515  Vector2 scale = GetContentScale();
1516  builder.Scale(scale.x, scale.y);
1517 
1518  builder.Save();
1519  // We need a small transform op to avoid a deferred save
1520  builder.Translate(1.0f, 1.0f);
1521  auto solid_filter =
1522  flutter::DlBlurMaskFilter::Make(flutter::DlBlurStyle::kSolid, 5.0f);
1523  flutter::DlPaint solid_alpha_paint =
1524  flutter::DlPaint() //
1525  .setMaskFilter(solid_filter) //
1526  .setColor(flutter::DlColor::kBlue()) //
1527  .setAlpha(0x7f);
1528  for (int x = 1; x <= 4; x++) {
1529  for (int y = 1; y <= 4; y++) {
1530  builder.DrawRect(SkRect::MakeXYWH(x * 100, y * 100, 80, 80),
1531  solid_alpha_paint);
1532  }
1533  }
1534  builder.Restore();
1535 
1536  builder.Save();
1537  builder.Translate(500.0f, 0.0f);
1538  auto normal_filter =
1539  flutter::DlBlurMaskFilter::Make(flutter::DlBlurStyle::kNormal, 5.0f);
1540  auto rotate_if = flutter::DlMatrixImageFilter::Make(
1541  Matrix::MakeRotationZ(Degrees(10)), flutter::DlImageSampling::kLinear);
1542  flutter::DlPaint normal_if_paint =
1543  flutter::DlPaint() //
1544  .setMaskFilter(solid_filter) //
1545  .setImageFilter(rotate_if) //
1546  .setColor(flutter::DlColor::kGreen()) //
1547  .setAlpha(0x7f);
1548  for (int x = 1; x <= 4; x++) {
1549  for (int y = 1; y <= 4; y++) {
1550  builder.DrawRect(SkRect::MakeXYWH(x * 100, y * 100, 80, 80),
1551  normal_if_paint);
1552  }
1553  }
1554  builder.Restore();
1555 
1556  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1557 }

References impeller::Matrix::MakeRotationZ(), scale, and x.

◆ TEST_P() [335/497]

impeller::testing::TEST_P ( DisplayListTest  ,
DrawPaintIgnoresMaskFilter   
)

Definition at line 1489 of file dl_unittests.cc.

1489  {
1490  flutter::DisplayListBuilder builder;
1491  builder.DrawPaint(flutter::DlPaint().setColor(flutter::DlColor::kWhite()));
1492 
1493  auto filter = flutter::DlBlurMaskFilter(flutter::DlBlurStyle::kNormal, 10.0f);
1494  builder.DrawCircle(SkPoint{300, 300}, 200,
1495  flutter::DlPaint().setMaskFilter(&filter));
1496 
1497  std::vector<flutter::DlColor> colors = {flutter::DlColor::kGreen(),
1498  flutter::DlColor::kGreen()};
1499  const float stops[2] = {0.0, 1.0};
1500  auto linear = flutter::DlColorSource::MakeLinear(
1501  {100.0, 100.0}, {300.0, 300.0}, 2, colors.data(), stops,
1502  flutter::DlTileMode::kRepeat);
1503  flutter::DlPaint blend_paint =
1504  flutter::DlPaint() //
1505  .setColorSource(linear) //
1506  .setBlendMode(flutter::DlBlendMode::kScreen);
1507  builder.DrawPaint(blend_paint);
1508 
1509  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1510 }

◆ TEST_P() [336/497]

impeller::testing::TEST_P ( DisplayListTest  ,
DrawShapes   
)

Definition at line 1298 of file dl_unittests.cc.

1298  {
1299  flutter::DisplayListBuilder builder;
1300  std::vector<flutter::DlStrokeJoin> joins = {
1301  flutter::DlStrokeJoin::kBevel,
1302  flutter::DlStrokeJoin::kRound,
1303  flutter::DlStrokeJoin::kMiter,
1304  };
1305  flutter::DlPaint paint = //
1306  flutter::DlPaint() //
1307  .setColor(flutter::DlColor::kWhite()) //
1308  .setDrawStyle(flutter::DlDrawStyle::kFill) //
1309  .setStrokeWidth(10);
1310  flutter::DlPaint stroke_paint = //
1311  flutter::DlPaint() //
1312  .setColor(flutter::DlColor::kWhite()) //
1313  .setDrawStyle(flutter::DlDrawStyle::kStroke) //
1314  .setStrokeWidth(10);
1315  SkPath path = SkPath().addPoly({{150, 50}, {160, 50}}, false);
1316 
1317  builder.Translate(300, 50);
1318  builder.Scale(0.8, 0.8);
1319  for (auto join : joins) {
1320  paint.setStrokeJoin(join);
1321  stroke_paint.setStrokeJoin(join);
1322  builder.DrawRect(SkRect::MakeXYWH(0, 0, 100, 100), paint);
1323  builder.DrawRect(SkRect::MakeXYWH(0, 150, 100, 100), stroke_paint);
1324  builder.DrawRRect(
1325  SkRRect::MakeRectXY(SkRect::MakeXYWH(150, 0, 100, 100), 30, 30), paint);
1326  builder.DrawRRect(
1327  SkRRect::MakeRectXY(SkRect::MakeXYWH(150, 150, 100, 100), 30, 30),
1328  stroke_paint);
1329  builder.DrawCircle(SkPoint{350, 50}, 50, paint);
1330  builder.DrawCircle(SkPoint{350, 200}, 50, stroke_paint);
1331  builder.Translate(0, 300);
1332  }
1333  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1334 }

◆ TEST_P() [337/497]

impeller::testing::TEST_P ( DisplayListTest  ,
DrawVerticesBlendModes   
)

Definition at line 1398 of file dl_unittests.cc.

1398  {
1399  std::vector<const char*> blend_mode_names;
1400  std::vector<flutter::DlBlendMode> blend_mode_values;
1401  {
1402  const std::vector<std::tuple<const char*, flutter::DlBlendMode>> blends = {
1403  // Pipeline blends (Porter-Duff alpha compositing)
1404  {"Clear", flutter::DlBlendMode::kClear},
1405  {"Source", flutter::DlBlendMode::kSrc},
1406  {"Destination", flutter::DlBlendMode::kDst},
1407  {"SourceOver", flutter::DlBlendMode::kSrcOver},
1408  {"DestinationOver", flutter::DlBlendMode::kDstOver},
1409  {"SourceIn", flutter::DlBlendMode::kSrcIn},
1410  {"DestinationIn", flutter::DlBlendMode::kDstIn},
1411  {"SourceOut", flutter::DlBlendMode::kSrcOut},
1412  {"DestinationOut", flutter::DlBlendMode::kDstOut},
1413  {"SourceATop", flutter::DlBlendMode::kSrcATop},
1414  {"DestinationATop", flutter::DlBlendMode::kDstATop},
1415  {"Xor", flutter::DlBlendMode::kXor},
1416  {"Plus", flutter::DlBlendMode::kPlus},
1417  {"Modulate", flutter::DlBlendMode::kModulate},
1418  // Advanced blends (color component blends)
1419  {"Screen", flutter::DlBlendMode::kScreen},
1420  {"Overlay", flutter::DlBlendMode::kOverlay},
1421  {"Darken", flutter::DlBlendMode::kDarken},
1422  {"Lighten", flutter::DlBlendMode::kLighten},
1423  {"ColorDodge", flutter::DlBlendMode::kColorDodge},
1424  {"ColorBurn", flutter::DlBlendMode::kColorBurn},
1425  {"HardLight", flutter::DlBlendMode::kHardLight},
1426  {"SoftLight", flutter::DlBlendMode::kSoftLight},
1427  {"Difference", flutter::DlBlendMode::kDifference},
1428  {"Exclusion", flutter::DlBlendMode::kExclusion},
1429  {"Multiply", flutter::DlBlendMode::kMultiply},
1430  {"Hue", flutter::DlBlendMode::kHue},
1431  {"Saturation", flutter::DlBlendMode::kSaturation},
1432  {"Color", flutter::DlBlendMode::kColor},
1433  {"Luminosity", flutter::DlBlendMode::kLuminosity},
1434  };
1435  assert(blends.size() ==
1436  static_cast<size_t>(flutter::DlBlendMode::kLastMode) + 1);
1437  for (const auto& [name, mode] : blends) {
1438  blend_mode_names.push_back(name);
1439  blend_mode_values.push_back(mode);
1440  }
1441  }
1442 
1443  auto callback = [&]() {
1444  static int current_blend_index = 3;
1445  static float dst_alpha = 1;
1446  static float src_alpha = 1;
1447  static float color0[4] = {1.0f, 0.0f, 0.0f, 1.0f};
1448  static float color1[4] = {0.0f, 1.0f, 0.0f, 1.0f};
1449  static float color2[4] = {0.0f, 0.0f, 1.0f, 1.0f};
1450  static float src_color[4] = {1.0f, 1.0f, 1.0f, 1.0f};
1451 
1452  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
1453  {
1454  ImGui::ListBox("Blending mode", &current_blend_index,
1455  blend_mode_names.data(), blend_mode_names.size());
1456  ImGui::SliderFloat("Source alpha", &src_alpha, 0, 1);
1457  ImGui::ColorEdit4("Color A", color0);
1458  ImGui::ColorEdit4("Color B", color1);
1459  ImGui::ColorEdit4("Color C", color2);
1460  ImGui::ColorEdit4("Source Color", src_color);
1461  ImGui::SliderFloat("Destination alpha", &dst_alpha, 0, 1);
1462  }
1463  ImGui::End();
1464 
1465  std::vector<DlPoint> positions = {DlPoint(100, 300), //
1466  DlPoint(200, 100), //
1467  DlPoint(300, 300)};
1468  std::vector<flutter::DlColor> colors = {
1469  toColor(color0).modulateOpacity(dst_alpha),
1470  toColor(color1).modulateOpacity(dst_alpha),
1471  toColor(color2).modulateOpacity(dst_alpha)};
1472 
1473  auto vertices = flutter::DlVertices::Make(
1474  flutter::DlVertexMode::kTriangles, 3, positions.data(),
1475  /*texture_coordinates=*/nullptr, colors.data());
1476 
1477  flutter::DisplayListBuilder builder;
1478  flutter::DlPaint paint;
1479 
1480  paint.setColor(toColor(src_color).modulateOpacity(src_alpha));
1481  builder.DrawVertices(vertices, blend_mode_values[current_blend_index],
1482  paint);
1483  return builder.Build();
1484  };
1485 
1486  ASSERT_TRUE(OpenPlaygroundHere(callback));
1487 }
flutter::DlColor toColor(const float *components)
Definition: dl_unittests.cc:41

References toColor().

◆ TEST_P() [338/497]

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().

◆ TEST_P() [339/497]

impeller::testing::TEST_P ( DisplayListTest  ,
MaskBlursApplyCorrectlyToColorSources   
)

Definition at line 1250 of file dl_unittests.cc.

1250  {
1251  auto blur_filter = std::make_shared<flutter::DlBlurMaskFilter>(
1252  flutter::DlBlurStyle::kNormal, 10);
1253 
1254  flutter::DisplayListBuilder builder;
1255 
1256  std::array<flutter::DlColor, 2> colors = {flutter::DlColor::kBlue(),
1257  flutter::DlColor::kGreen()};
1258  std::array<float, 2> stops = {0, 1};
1259  auto texture = CreateTextureForFixture("airplane.jpg");
1260  auto matrix = flutter::DlMatrix::MakeTranslation({-300, -110});
1261  std::array<std::shared_ptr<flutter::DlColorSource>, 2> color_sources = {
1262  flutter::DlColorSource::MakeImage(
1263  DlImageImpeller::Make(texture), flutter::DlTileMode::kRepeat,
1264  flutter::DlTileMode::kRepeat, flutter::DlImageSampling::kLinear,
1265  &matrix),
1266  flutter::DlColorSource::MakeLinear(
1267  flutter::DlPoint(0, 0), flutter::DlPoint(100, 50), 2, colors.data(),
1268  stops.data(), flutter::DlTileMode::kClamp),
1269  };
1270 
1271  builder.Save();
1272  builder.Translate(0, 100);
1273  for (const auto& color_source : color_sources) {
1274  flutter::DlPaint paint;
1275  paint.setColorSource(color_source);
1276  paint.setMaskFilter(blur_filter);
1277 
1278  builder.Save();
1279  builder.Translate(100, 0);
1280  paint.setDrawStyle(flutter::DlDrawStyle::kFill);
1281  builder.DrawRRect(SkRRect::MakeRectXY(SkRect::MakeWH(100, 50), 30, 30),
1282  paint);
1283 
1284  paint.setDrawStyle(flutter::DlDrawStyle::kStroke);
1285  paint.setStrokeWidth(10);
1286  builder.Translate(200, 0);
1287  builder.DrawRRect(SkRRect::MakeRectXY(SkRect::MakeWH(100, 50), 30, 30),
1288  paint);
1289 
1290  builder.Restore();
1291  builder.Translate(0, 100);
1292  }
1293  builder.Restore();
1294 
1295  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1296 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [340/497]

impeller::testing::TEST_P ( DisplayListTest  ,
NinePatchImagePrecision   
)

Definition at line 789 of file dl_unittests.cc.

789  {
790  // Draw a nine patch image with colored corners and verify that the corner
791  // color does not leak outside the intended region.
792  auto texture = CreateTextureForFixture("nine_patch_corners.png");
793  flutter::DisplayListBuilder builder;
794  builder.DrawImageNine(DlImageImpeller::Make(texture),
795  SkIRect::MakeXYWH(10, 10, 1, 1),
796  SkRect::MakeXYWH(0, 0, 200, 100),
797  flutter::DlFilterMode::kNearest, nullptr);
798  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
799 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [341/497]

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 stroke_width.

◆ TEST_P() [342/497]

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 }

◆ TEST_P() [343/497]

impeller::testing::TEST_P ( DriverInfoVKTest  ,
CanDumpToLog   
)

Definition at line 29 of file driver_info_vk_unittests.cc.

29  {
30  ASSERT_TRUE(GetContext());
31  const auto& driver_info =
32  SurfaceContextVK::Cast(*GetContext()).GetParent()->GetDriverInfo();
33  ASSERT_NE(driver_info, nullptr);
34  fml::testing::LogCapture log;
35  driver_info->DumpToLog();
36  EXPECT_TRUE(log.str().find("Driver Information") != std::string::npos);
37 }

References impeller::BackendCast< SurfaceContextVK, Context >::Cast(), and impeller::SurfaceContextVK::GetParent().

◆ TEST_P() [344/497]

impeller::testing::TEST_P ( DriverInfoVKTest  ,
CanQueryDriverInfo   
)

Definition at line 16 of file driver_info_vk_unittests.cc.

16  {
17  ASSERT_TRUE(GetContext());
18  const auto& driver_info =
19  SurfaceContextVK::Cast(*GetContext()).GetParent()->GetDriverInfo();
20  ASSERT_NE(driver_info, nullptr);
21  // 1.1 is the base Impeller version. The driver can't be lower than that.
22  ASSERT_TRUE(driver_info->GetAPIVersion().IsAtLeast(Version{1, 1, 0}));
23  ASSERT_NE(driver_info->GetVendor(), VendorVK::kUnknown);
24  ASSERT_NE(driver_info->GetDeviceType(), DeviceTypeVK::kUnknown);
25  ASSERT_NE(driver_info->GetDriverName(), "");
26  EXPECT_FALSE(driver_info->IsKnownBadDriver());
27 }

References impeller::BackendCast< SurfaceContextVK, Context >::Cast(), impeller::SurfaceContextVK::GetParent(), and impeller::kUnknown.

◆ TEST_P() [345/497]

impeller::testing::TEST_P ( EntityPassTargetTest  ,
SwapWithMSAAImplicitResolve   
)

Definition at line 47 of file entity_pass_target_unittests.cc.

47  {
48  auto content_context = GetContentContext();
49  auto buffer = content_context->GetContext()->CreateCommandBuffer();
50  auto context = content_context->GetContext();
51  auto& allocator = *context->GetResourceAllocator();
52 
53  // Emulate implicit MSAA resolve by making color resolve and msaa texture the
54  // same.
55  RenderTarget render_target;
56  {
57  PixelFormat pixel_format =
58  context->GetCapabilities()->GetDefaultColorFormat();
59 
60  // Create MSAA color texture.
61 
62  TextureDescriptor color0_tex_desc;
63  color0_tex_desc.storage_mode = StorageMode::kDevicePrivate;
64  color0_tex_desc.type = TextureType::kTexture2DMultisample;
65  color0_tex_desc.sample_count = SampleCount::kCount4;
66  color0_tex_desc.format = pixel_format;
67  color0_tex_desc.size = ISize{100, 100};
68  color0_tex_desc.usage = TextureUsage::kRenderTarget;
69 
70  auto color0_msaa_tex = allocator.CreateTexture(color0_tex_desc);
71 
72  // Color attachment.
73 
74  ColorAttachment color0;
75  color0.load_action = LoadAction::kDontCare;
76  color0.store_action = StoreAction::kStoreAndMultisampleResolve;
77  color0.texture = color0_msaa_tex;
78  color0.resolve_texture = color0_msaa_tex;
79 
80  render_target.SetColorAttachment(color0, 0u);
81  render_target.SetStencilAttachment(std::nullopt);
82  }
83 
84  auto entity_pass_target = EntityPassTarget(render_target, false, true);
85 
86  auto color0 = entity_pass_target.GetRenderTarget().GetColorAttachment(0);
87  auto msaa_tex = color0.texture;
88  auto resolve_tex = color0.resolve_texture;
89 
90  ASSERT_EQ(msaa_tex, resolve_tex);
91 
92  FML_DCHECK(content_context);
93  entity_pass_target.Flip(*content_context);
94 
95  color0 = entity_pass_target.GetRenderTarget().GetColorAttachment(0);
96 
97  ASSERT_NE(msaa_tex, color0.texture);
98  ASSERT_NE(resolve_tex, color0.resolve_texture);
99  ASSERT_EQ(color0.texture, color0.resolve_texture);
100 }

References impeller::TextureDescriptor::format, impeller::kCount4, impeller::kDevicePrivate, impeller::kDontCare, impeller::kRenderTarget, impeller::kStoreAndMultisampleResolve, impeller::kTexture2DMultisample, impeller::Attachment::load_action, impeller::Attachment::resolve_texture, impeller::TextureDescriptor::sample_count, impeller::RenderTarget::SetColorAttachment(), impeller::RenderTarget::SetStencilAttachment(), impeller::TextureDescriptor::size, impeller::TextureDescriptor::storage_mode, impeller::Attachment::store_action, impeller::Attachment::texture, impeller::TextureDescriptor::type, and impeller::TextureDescriptor::usage.

◆ TEST_P() [346/497]

impeller::testing::TEST_P ( EntityPassTargetTest  ,
SwapWithMSAATexture   
)

Definition at line 19 of file entity_pass_target_unittests.cc.

19  {
20  if (GetContentContext()
21  ->GetDeviceCapabilities()
22  .SupportsImplicitResolvingMSAA()) {
23  GTEST_SKIP() << "Implicit MSAA is used on this device.";
24  }
25  auto content_context = GetContentContext();
26  auto buffer = content_context->GetContext()->CreateCommandBuffer();
27  auto render_target =
28  GetContentContext()->GetRenderTargetCache()->CreateOffscreenMSAA(
29  *content_context->GetContext(), {100, 100},
30  /*mip_count=*/1);
31 
32  auto entity_pass_target = EntityPassTarget(render_target, false, false);
33 
34  auto color0 = entity_pass_target.GetRenderTarget().GetColorAttachment(0);
35  auto msaa_tex = color0.texture;
36  auto resolve_tex = color0.resolve_texture;
37 
38  FML_DCHECK(content_context);
39  entity_pass_target.Flip(*content_context);
40 
41  color0 = entity_pass_target.GetRenderTarget().GetColorAttachment(0);
42 
43  ASSERT_EQ(msaa_tex, color0.texture);
44  ASSERT_NE(resolve_tex, color0.resolve_texture);
45 }

◆ TEST_P() [347/497]

impeller::testing::TEST_P ( EntityTest  ,
BezierCircleScaled   
)

Definition at line 825 of file entity_unittests.cc.

825  {
826  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
827  static float scale = 20;
828 
829  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
830  ImGui::SliderFloat("Scale", &scale, 1, 100);
831  ImGui::End();
832 
833  Entity entity;
834  entity.SetTransform(Matrix::MakeScale(GetContentScale()));
835  auto path = PathBuilder{}
836  .MoveTo({97.325, 34.818})
837  .CubicCurveTo({98.50862885295136, 34.81812293973836},
838  {99.46822048142015, 33.85863261475589},
839  {99.46822048142015, 32.67499810206613})
840  .CubicCurveTo({99.46822048142015, 31.491363589376355},
841  {98.50862885295136, 30.53187326439389},
842  {97.32499434685802, 30.531998226542708})
843  .CubicCurveTo({96.14153655073771, 30.532123170035373},
844  {95.18222070648729, 31.491540299350355},
845  {95.18222070648729, 32.67499810206613})
846  .CubicCurveTo({95.18222070648729, 33.85845590478189},
847  {96.14153655073771, 34.81787303409686},
848  {97.32499434685802, 34.81799797758954})
849  .Close()
850  .TakePath();
851  entity.SetTransform(
852  Matrix::MakeScale({scale, scale, 1.0}).Translate({-90, -20, 0}));
853 
854  std::unique_ptr<Geometry> geom = Geometry::MakeFillPath(path);
855 
856  auto contents = std::make_shared<SolidColorContents>();
857  contents->SetColor(Color::Red());
858  contents->SetGeometry(geom.get());
859 
860  entity.SetContents(contents);
861  return entity.Render(context, pass);
862  };
863  ASSERT_TRUE(OpenPlaygroundHere(callback));
864 }

References impeller::Close(), impeller::Geometry::MakeFillPath(), impeller::Matrix::MakeScale(), impeller::PathBuilder::MoveTo(), impeller::Color::Red(), impeller::Entity::Render(), scale, impeller::Entity::SetContents(), and impeller::Entity::SetTransform().

◆ TEST_P() [348/497]

impeller::testing::TEST_P ( EntityTest  ,
BlendingModeOptions   
)

Definition at line 694 of file entity_unittests.cc.

694  {
695  std::vector<const char*> blend_mode_names;
696  std::vector<BlendMode> blend_mode_values;
697  {
698  // Force an exhausiveness check with a switch. When adding blend modes,
699  // update this switch with a new name/value to make it selectable in the
700  // test GUI.
701 
702  const BlendMode b{};
703  static_assert(b == BlendMode::kClear); // Ensure the first item in
704  // the switch is the first
705  // item in the enum.
706  static_assert(Entity::kLastPipelineBlendMode == BlendMode::kModulate);
707  switch (b) {
708  case BlendMode::kClear:
709  blend_mode_names.push_back("Clear");
710  blend_mode_values.push_back(BlendMode::kClear);
711  case BlendMode::kSource:
712  blend_mode_names.push_back("Source");
713  blend_mode_values.push_back(BlendMode::kSource);
714  case BlendMode::kDestination:
715  blend_mode_names.push_back("Destination");
716  blend_mode_values.push_back(BlendMode::kDestination);
717  case BlendMode::kSourceOver:
718  blend_mode_names.push_back("SourceOver");
719  blend_mode_values.push_back(BlendMode::kSourceOver);
720  case BlendMode::kDestinationOver:
721  blend_mode_names.push_back("DestinationOver");
722  blend_mode_values.push_back(BlendMode::kDestinationOver);
723  case BlendMode::kSourceIn:
724  blend_mode_names.push_back("SourceIn");
725  blend_mode_values.push_back(BlendMode::kSourceIn);
726  case BlendMode::kDestinationIn:
727  blend_mode_names.push_back("DestinationIn");
728  blend_mode_values.push_back(BlendMode::kDestinationIn);
729  case BlendMode::kSourceOut:
730  blend_mode_names.push_back("SourceOut");
731  blend_mode_values.push_back(BlendMode::kSourceOut);
732  case BlendMode::kDestinationOut:
733  blend_mode_names.push_back("DestinationOut");
734  blend_mode_values.push_back(BlendMode::kDestinationOut);
735  case BlendMode::kSourceATop:
736  blend_mode_names.push_back("SourceATop");
737  blend_mode_values.push_back(BlendMode::kSourceATop);
738  case BlendMode::kDestinationATop:
739  blend_mode_names.push_back("DestinationATop");
740  blend_mode_values.push_back(BlendMode::kDestinationATop);
741  case BlendMode::kXor:
742  blend_mode_names.push_back("Xor");
743  blend_mode_values.push_back(BlendMode::kXor);
744  case BlendMode::kPlus:
745  blend_mode_names.push_back("Plus");
746  blend_mode_values.push_back(BlendMode::kPlus);
747  case BlendMode::kModulate:
748  blend_mode_names.push_back("Modulate");
749  blend_mode_values.push_back(BlendMode::kModulate);
750  };
751  }
752 
753  auto callback = [&](ContentContext& context, RenderPass& pass) {
754  auto world_matrix = Matrix::MakeScale(GetContentScale());
755  auto draw_rect = [&context, &pass, &world_matrix](
756  Rect rect, Color color, BlendMode blend_mode) -> bool {
757  using VS = SolidFillPipeline::VertexShader;
758  using FS = SolidFillPipeline::FragmentShader;
759 
760  VertexBufferBuilder<VS::PerVertexData> vtx_builder;
761  {
762  auto r = rect.GetLTRB();
763  vtx_builder.AddVertices({
764  {Point(r[0], r[1])},
765  {Point(r[2], r[1])},
766  {Point(r[2], r[3])},
767  {Point(r[0], r[1])},
768  {Point(r[2], r[3])},
769  {Point(r[0], r[3])},
770  });
771  }
772 
773  pass.SetCommandLabel("Blended Rectangle");
774  auto options = OptionsFromPass(pass);
775  options.blend_mode = blend_mode;
776  options.primitive_type = PrimitiveType::kTriangle;
777  pass.SetPipeline(context.GetSolidFillPipeline(options));
778  pass.SetVertexBuffer(
779  vtx_builder.CreateVertexBuffer(context.GetTransientsBuffer()));
780 
781  VS::FrameInfo frame_info;
782  frame_info.mvp = pass.GetOrthographicTransform() * world_matrix;
783  VS::BindFrameInfo(
784  pass, context.GetTransientsBuffer().EmplaceUniform(frame_info));
785  FS::FragInfo frag_info;
786  frag_info.color = color.Premultiply();
787  FS::BindFragInfo(
788  pass, context.GetTransientsBuffer().EmplaceUniform(frame_info));
789  return pass.Draw().ok();
790  };
791 
792  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
793  static Color color1(1, 0, 0, 0.5), color2(0, 1, 0, 0.5);
794  ImGui::ColorEdit4("Color 1", reinterpret_cast<float*>(&color1));
795  ImGui::ColorEdit4("Color 2", reinterpret_cast<float*>(&color2));
796  static int current_blend_index = 3;
797  ImGui::ListBox("Blending mode", &current_blend_index,
798  blend_mode_names.data(), blend_mode_names.size());
799  ImGui::End();
800 
801  BlendMode selected_mode = blend_mode_values[current_blend_index];
802 
803  Point a, b, c, d;
804  PlaygroundPoint point_a(Point(400, 100), 20, Color::White());
805  PlaygroundPoint point_b(Point(200, 300), 20, Color::White());
806  std::tie(a, b) = DrawPlaygroundLine(point_a, point_b);
807  PlaygroundPoint point_c(Point(470, 190), 20, Color::White());
808  PlaygroundPoint point_d(Point(270, 390), 20, Color::White());
809  std::tie(c, d) = DrawPlaygroundLine(point_c, point_d);
810 
811  bool result = true;
812  result = result &&
813  draw_rect(Rect::MakeXYWH(0, 0, pass.GetRenderTargetSize().width,
814  pass.GetRenderTargetSize().height),
815  Color(), BlendMode::kClear);
816  result = result && draw_rect(Rect::MakeLTRB(a.x, a.y, b.x, b.y), color1,
817  BlendMode::kSourceOver);
818  result = result && draw_rect(Rect::MakeLTRB(c.x, c.y, d.x, d.y), color2,
819  selected_mode);
820  return result;
821  };
822  ASSERT_TRUE(OpenPlaygroundHere(callback));
823 }
GlyphAtlasPipeline::VertexShader VS
GlyphAtlasPipeline::FragmentShader FS
ContentContextOptions OptionsFromPass(const RenderPass &pass)
Definition: contents.cc:19

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), impeller::saturated::b, impeller::VertexBufferBuilder< VertexType_, IndexType_ >::CreateVertexBuffer(), impeller::DrawPlaygroundLine(), impeller::HostBuffer::EmplaceUniform(), impeller::ContentContext::GetSolidFillPipeline(), impeller::ContentContext::GetTransientsBuffer(), impeller::kClear, impeller::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() [349/497]

impeller::testing::TEST_P ( EntityTest  ,
BorderMaskBlurCoverageIsCorrect   
)

Definition at line 1254 of file entity_unittests.cc.

1254  {
1255  auto fill = std::make_shared<SolidColorContents>();
1256  auto geom = Geometry::MakeFillPath(
1257  PathBuilder{}.AddRect(Rect::MakeXYWH(0, 0, 300, 400)).TakePath());
1258  fill->SetGeometry(geom.get());
1259  fill->SetColor(Color::CornflowerBlue());
1260  auto border_mask_blur = FilterContents::MakeBorderMaskBlur(
1261  FilterInput::Make(fill), Radius{3}, Radius{4});
1262 
1263  {
1264  Entity e;
1265  e.SetTransform(Matrix());
1266  auto actual = border_mask_blur->GetCoverage(e);
1267  auto expected = Rect::MakeXYWH(-3, -4, 306, 408);
1268  ASSERT_TRUE(actual.has_value());
1269  ASSERT_RECT_NEAR(actual.value(), expected);
1270  }
1271 
1272  {
1273  Entity e;
1274  e.SetTransform(Matrix::MakeRotationZ(Radians{kPi / 4}));
1275  auto actual = border_mask_blur->GetCoverage(e);
1276  auto expected = Rect::MakeXYWH(-287.792, -4.94975, 504.874, 504.874);
1277  ASSERT_TRUE(actual.has_value());
1278  ASSERT_RECT_NEAR(actual.value(), expected);
1279  }
1280 }

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() [350/497]

impeller::testing::TEST_P ( EntityTest  ,
CanComputeGeometryForEmptyPathsWithoutCrashing   
)

Definition at line 2247 of file entity_unittests.cc.

2247  {
2248  PathBuilder builder = {};
2249  builder.AddRect(Rect::MakeLTRB(0, 0, 0, 0));
2250  Path path = builder.TakePath();
2251 
2252  EXPECT_TRUE(path.GetBoundingBox()->IsEmpty());
2253 
2254  auto geom = Geometry::MakeFillPath(path);
2255 
2256  Entity entity;
2257  RenderTarget target =
2258  GetContentContext()->GetRenderTargetCache()->CreateOffscreen(
2259  *GetContext(), {1, 1}, 1u);
2260  testing::MockRenderPass render_pass(GetContext(), target);
2261  auto position_result =
2262  geom->GetPositionBuffer(*GetContentContext(), entity, render_pass);
2263 
2264  EXPECT_EQ(position_result.vertex_buffer.vertex_count, 0u);
2265 
2266  EXPECT_EQ(geom->GetResultMode(), GeometryResult::Mode::kNormal);
2267 }

References impeller::PathBuilder::AddRect(), impeller::Path::GetBoundingBox(), impeller::GeometryResult::kNormal, impeller::Geometry::MakeFillPath(), impeller::TRect< Scalar >::MakeLTRB(), and impeller::PathBuilder::TakePath().

◆ TEST_P() [351/497]

impeller::testing::TEST_P ( EntityTest  ,
CanCreateEntity   
)

Definition at line 68 of file entity_unittests.cc.

68  {
69  Entity entity;
70  ASSERT_TRUE(entity.GetTransform().IsIdentity());
71 }

References impeller::Entity::GetTransform(), and impeller::Matrix::IsIdentity().

◆ TEST_P() [352/497]

impeller::testing::TEST_P ( EntityTest  ,
CanDrawCorrectlyWithRotatedTransform   
)

Definition at line 362 of file entity_unittests.cc.

362  {
363  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
364  const char* input_axis[] = {"X", "Y", "Z"};
365  static int rotation_axis_index = 0;
366  static float rotation = 0;
367  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
368  ImGui::SliderFloat("Rotation", &rotation, -kPi, kPi);
369  ImGui::Combo("Rotation Axis", &rotation_axis_index, input_axis,
370  sizeof(input_axis) / sizeof(char*));
371  Matrix rotation_matrix;
372  switch (rotation_axis_index) {
373  case 0:
374  rotation_matrix = Matrix::MakeRotationX(Radians(rotation));
375  break;
376  case 1:
377  rotation_matrix = Matrix::MakeRotationY(Radians(rotation));
378  break;
379  case 2:
380  rotation_matrix = Matrix::MakeRotationZ(Radians(rotation));
381  break;
382  default:
383  rotation_matrix = Matrix{};
384  break;
385  }
386 
387  if (ImGui::Button("Reset")) {
388  rotation = 0;
389  }
390  ImGui::End();
391  Matrix current_transform =
392  Matrix::MakeScale(GetContentScale())
393  .MakeTranslation(
394  Vector3(Point(pass.GetRenderTargetSize().width / 2.0,
395  pass.GetRenderTargetSize().height / 2.0)));
396  Matrix result_transform = current_transform * rotation_matrix;
397  Path path =
398  PathBuilder{}.AddRect(Rect::MakeXYWH(-300, -400, 600, 800)).TakePath();
399 
400  Entity entity;
401  entity.SetTransform(result_transform);
402 
403  std::unique_ptr<Geometry> geom = Geometry::MakeFillPath(path);
404 
405  auto contents = std::make_shared<SolidColorContents>();
406  contents->SetColor(Color::Red());
407  contents->SetGeometry(geom.get());
408 
409  entity.SetContents(contents);
410  return entity.Render(context, pass);
411  };
412  ASSERT_TRUE(OpenPlaygroundHere(callback));
413 }

References impeller::PathBuilder::AddRect(), impeller::kPi, impeller::Geometry::MakeFillPath(), impeller::Matrix::MakeRotationX(), impeller::Matrix::MakeRotationY(), impeller::Matrix::MakeRotationZ(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeTranslation(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Color::Red(), impeller::Entity::Render(), impeller::Entity::SetContents(), impeller::Entity::SetTransform(), and impeller::PathBuilder::TakePath().

◆ TEST_P() [353/497]

impeller::testing::TEST_P ( EntityTest  ,
CanRenderEmptyPathsWithoutCrashing   
)

Definition at line 2269 of file entity_unittests.cc.

2269  {
2270  PathBuilder builder = {};
2271  builder.AddRect(Rect::MakeLTRB(0, 0, 0, 0));
2272  Path path = builder.TakePath();
2273 
2274  EXPECT_TRUE(path.GetBoundingBox()->IsEmpty());
2275 
2276  auto contents = std::make_shared<SolidColorContents>();
2277  std::unique_ptr<Geometry> geom = Geometry::MakeFillPath(path);
2278  contents->SetGeometry(geom.get());
2279  contents->SetColor(Color::Red());
2280 
2281  Entity entity;
2282  entity.SetTransform(Matrix::MakeScale(GetContentScale()));
2283  entity.SetContents(contents);
2284 
2285  ASSERT_TRUE(OpenPlaygroundHere(std::move(entity)));
2286 }

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() [354/497]

impeller::testing::TEST_P ( EntityTest  ,
ColorFilterContentsWithLargeGeometry   
)

Definition at line 2088 of file entity_unittests.cc.

2088  {
2089  Entity entity;
2090  entity.SetTransform(Matrix::MakeScale(GetContentScale()));
2091  auto src_contents = std::make_shared<SolidColorContents>();
2092  auto src_geom = Geometry::MakeRect(Rect::MakeLTRB(-300, -500, 30000, 50000));
2093  src_contents->SetGeometry(src_geom.get());
2094  src_contents->SetColor(Color::Red());
2095 
2096  auto dst_contents = std::make_shared<SolidColorContents>();
2097  auto dst_geom = Geometry::MakeRect(Rect::MakeLTRB(300, 500, 20000, 30000));
2098  dst_contents->SetGeometry(dst_geom.get());
2099  dst_contents->SetColor(Color::Blue());
2100 
2101  auto contents = ColorFilterContents::MakeBlend(
2102  BlendMode::kSourceOver, {FilterInput::Make(dst_contents, false),
2103  FilterInput::Make(src_contents, false)});
2104  entity.SetContents(std::move(contents));
2105  ASSERT_TRUE(OpenPlaygroundHere(std::move(entity)));
2106 }

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() [355/497]

impeller::testing::TEST_P ( EntityTest  ,
ColorFilterWithForegroundColorAdvancedBlend   
)

Definition at line 1855 of file entity_unittests.cc.

1855  {
1856  auto image = CreateTextureForFixture("boston.jpg");
1857  auto filter = ColorFilterContents::MakeBlend(
1858  BlendMode::kColorBurn, FilterInput::Make({image}), Color::Red());
1859 
1860  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
1861  Entity entity;
1862  entity.SetTransform(Matrix::MakeScale(GetContentScale()) *
1863  Matrix::MakeTranslation({500, 300}) *
1864  Matrix::MakeScale(Vector2{0.5, 0.5}));
1865  entity.SetContents(filter);
1866  return entity.Render(context, pass);
1867  };
1868  ASSERT_TRUE(OpenPlaygroundHere(callback));
1869 }

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() [356/497]

impeller::testing::TEST_P ( EntityTest  ,
ColorFilterWithForegroundColorClearBlend   
)

Definition at line 1871 of file entity_unittests.cc.

1871  {
1872  auto image = CreateTextureForFixture("boston.jpg");
1873  auto filter = ColorFilterContents::MakeBlend(
1874  BlendMode::kClear, FilterInput::Make({image}), Color::Red());
1875 
1876  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
1877  Entity entity;
1878  entity.SetTransform(Matrix::MakeScale(GetContentScale()) *
1879  Matrix::MakeTranslation({500, 300}) *
1880  Matrix::MakeScale(Vector2{0.5, 0.5}));
1881  entity.SetContents(filter);
1882  return entity.Render(context, pass);
1883  };
1884  ASSERT_TRUE(OpenPlaygroundHere(callback));
1885 }

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() [357/497]

impeller::testing::TEST_P ( EntityTest  ,
ColorFilterWithForegroundColorDstBlend   
)

Definition at line 1903 of file entity_unittests.cc.

1903  {
1904  auto image = CreateTextureForFixture("boston.jpg");
1905  auto filter = ColorFilterContents::MakeBlend(
1906  BlendMode::kDestination, FilterInput::Make({image}), Color::Red());
1907 
1908  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
1909  Entity entity;
1910  entity.SetTransform(Matrix::MakeScale(GetContentScale()) *
1911  Matrix::MakeTranslation({500, 300}) *
1912  Matrix::MakeScale(Vector2{0.5, 0.5}));
1913  entity.SetContents(filter);
1914  return entity.Render(context, pass);
1915  };
1916  ASSERT_TRUE(OpenPlaygroundHere(callback));
1917 }

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() [358/497]

impeller::testing::TEST_P ( EntityTest  ,
ColorFilterWithForegroundColorSrcBlend   
)

Definition at line 1887 of file entity_unittests.cc.

1887  {
1888  auto image = CreateTextureForFixture("boston.jpg");
1889  auto filter = ColorFilterContents::MakeBlend(
1890  BlendMode::kSource, FilterInput::Make({image}), Color::Red());
1891 
1892  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
1893  Entity entity;
1894  entity.SetTransform(Matrix::MakeScale(GetContentScale()) *
1895  Matrix::MakeTranslation({500, 300}) *
1896  Matrix::MakeScale(Vector2{0.5, 0.5}));
1897  entity.SetContents(filter);
1898  return entity.Render(context, pass);
1899  };
1900  ASSERT_TRUE(OpenPlaygroundHere(callback));
1901 }

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() [359/497]

impeller::testing::TEST_P ( EntityTest  ,
ColorFilterWithForegroundColorSrcInBlend   
)

Definition at line 1919 of file entity_unittests.cc.

1919  {
1920  auto image = CreateTextureForFixture("boston.jpg");
1921  auto filter = ColorFilterContents::MakeBlend(
1922  BlendMode::kSourceIn, FilterInput::Make({image}), Color::Red());
1923 
1924  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
1925  Entity entity;
1926  entity.SetTransform(Matrix::MakeScale(GetContentScale()) *
1927  Matrix::MakeTranslation({500, 300}) *
1928  Matrix::MakeScale(Vector2{0.5, 0.5}));
1929  entity.SetContents(filter);
1930  return entity.Render(context, pass);
1931  };
1932  ASSERT_TRUE(OpenPlaygroundHere(callback));
1933 }

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() [360/497]

impeller::testing::TEST_P ( EntityTest  ,
ColorMatrixFilterCoverageIsCorrect   
)

Definition at line 1381 of file entity_unittests.cc.

1381  {
1382  // Set up a simple color background.
1383  auto fill = std::make_shared<SolidColorContents>();
1384  auto geom = Geometry::MakeFillPath(
1385  PathBuilder{}.AddRect(Rect::MakeXYWH(0, 0, 300, 400)).TakePath());
1386  fill->SetGeometry(geom.get());
1387  fill->SetColor(Color::Coral());
1388 
1389  // Set the color matrix filter.
1390  ColorMatrix matrix = {
1391  1, 1, 1, 1, 1, //
1392  1, 1, 1, 1, 1, //
1393  1, 1, 1, 1, 1, //
1394  1, 1, 1, 1, 1, //
1395  };
1396 
1397  auto filter =
1398  ColorFilterContents::MakeColorMatrix(FilterInput::Make(fill), matrix);
1399 
1400  Entity e;
1401  e.SetTransform(Matrix());
1402 
1403  // Confirm that the actual filter coverage matches the expected coverage.
1404  auto actual = filter->GetCoverage(e);
1405  auto expected = Rect::MakeXYWH(0, 0, 300, 400);
1406 
1407  ASSERT_TRUE(actual.has_value());
1408  ASSERT_RECT_NEAR(actual.value(), expected);
1409 }

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() [361/497]

impeller::testing::TEST_P ( EntityTest  ,
ColorMatrixFilterEditable   
)

Definition at line 1411 of file entity_unittests.cc.

1411  {
1412  auto bay_bridge = CreateTextureForFixture("bay_bridge.jpg");
1413  ASSERT_TRUE(bay_bridge);
1414 
1415  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
1416  // UI state.
1417  static ColorMatrix color_matrix = {
1418  1, 0, 0, 0, 0, //
1419  0, 3, 0, 0, 0, //
1420  0, 0, 1, 0, 0, //
1421  0, 0, 0, 1, 0, //
1422  };
1423  static float offset[2] = {500, 400};
1424  static float rotation = 0;
1425  static float scale[2] = {0.65, 0.65};
1426  static float skew[2] = {0, 0};
1427 
1428  // Define the ImGui
1429  ImGui::Begin("Color Matrix", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
1430  {
1431  std::string label = "##1";
1432  for (int i = 0; i < 20; i += 5) {
1433  ImGui::InputScalarN(label.c_str(), ImGuiDataType_Float,
1434  &(color_matrix.array[i]), 5, nullptr, nullptr,
1435  "%.2f", 0);
1436  label[2]++;
1437  }
1438 
1439  ImGui::SliderFloat2("Translation", &offset[0], 0,
1440  pass.GetRenderTargetSize().width);
1441  ImGui::SliderFloat("Rotation", &rotation, 0, kPi * 2);
1442  ImGui::SliderFloat2("Scale", &scale[0], 0, 3);
1443  ImGui::SliderFloat2("Skew", &skew[0], -3, 3);
1444  }
1445  ImGui::End();
1446 
1447  // Set the color matrix filter.
1448  auto filter = ColorFilterContents::MakeColorMatrix(
1449  FilterInput::Make(bay_bridge), color_matrix);
1450 
1451  // Define the entity with the color matrix filter.
1452  Entity entity;
1453  entity.SetTransform(
1454  Matrix::MakeScale(GetContentScale()) *
1455  Matrix::MakeTranslation(Vector3(offset[0], offset[1])) *
1456  Matrix::MakeRotationZ(Radians(rotation)) *
1457  Matrix::MakeScale(Vector2(scale[0], scale[1])) *
1458  Matrix::MakeSkew(skew[0], skew[1]) *
1459  Matrix::MakeTranslation(-Point(bay_bridge->GetSize()) / 2));
1460  entity.SetContents(filter);
1461  entity.Render(context, pass);
1462 
1463  return true;
1464  };
1465 
1466  ASSERT_TRUE(OpenPlaygroundHere(callback));
1467 }

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() [362/497]

impeller::testing::TEST_P ( EntityTest  ,
ConicalGradientContentsIsOpaque   
)

Definition at line 1976 of file entity_unittests.cc.

1976  {
1977  Matrix matrix;
1978  ConicalGradientContents contents;
1979  auto geom = Geometry::MakeRect(Rect::MakeLTRB(0, 0, 10, 10));
1980  contents.SetGeometry(geom.get());
1981 
1982  contents.SetColors({Color::CornflowerBlue()});
1983  EXPECT_FALSE(contents.IsOpaque(matrix));
1984  contents.SetColors({Color::CornflowerBlue().WithAlpha(0.5)});
1985  EXPECT_FALSE(contents.IsOpaque(matrix));
1986 
1987  // Create stroked path that required alpha coverage.
1988  geom = Geometry::MakeStrokePath(
1989  PathBuilder{}.AddLine({0, 0}, {100, 100}).TakePath(),
1990  /*stroke_width=*/0.05);
1991  contents.SetGeometry(geom.get());
1992  contents.SetColors({Color::CornflowerBlue()});
1993 
1994  EXPECT_FALSE(contents.IsOpaque(matrix));
1995 }

References impeller::PathBuilder::AddLine(), impeller::Color::CornflowerBlue(), impeller::Contents::IsOpaque(), impeller::TRect< Scalar >::MakeLTRB(), impeller::Geometry::MakeRect(), impeller::Geometry::MakeStrokePath(), impeller::ConicalGradientContents::SetColors(), impeller::ColorSourceContents::SetGeometry(), and impeller::Color::WithAlpha().

◆ TEST_P() [363/497]

impeller::testing::TEST_P ( EntityTest  ,
ContentContextOptionsHasReasonableHashFunctions   
)

Definition at line 2155 of file entity_unittests.cc.

2155  {
2156  ContentContextOptions opts;
2157  auto hash_a = opts.ToKey();
2158 
2159  opts.blend_mode = BlendMode::kColorBurn;
2160  auto hash_b = opts.ToKey();
2161 
2162  opts.has_depth_stencil_attachments = false;
2163  auto hash_c = opts.ToKey();
2164 
2165  opts.primitive_type = PrimitiveType::kPoint;
2166  auto hash_d = opts.ToKey();
2167 
2168  EXPECT_NE(hash_a, hash_b);
2169  EXPECT_NE(hash_b, hash_c);
2170  EXPECT_NE(hash_c, hash_d);
2171 }

References impeller::ContentContextOptions::blend_mode, impeller::ContentContextOptions::has_depth_stencil_attachments, impeller::kColorBurn, impeller::kPoint, impeller::ContentContextOptions::primitive_type, and impeller::ContentContextOptions::ToKey().

◆ TEST_P() [364/497]

impeller::testing::TEST_P ( EntityTest  ,
ContentsGetBoundsForEmptyPathReturnsNullopt   
)

Definition at line 1192 of file entity_unittests.cc.

1192  {
1193  Entity entity;
1194  entity.SetContents(std::make_shared<SolidColorContents>());
1195  ASSERT_FALSE(entity.GetCoverage().has_value());
1196 }

References impeller::Entity::GetCoverage(), and impeller::Entity::SetContents().

◆ TEST_P() [365/497]

impeller::testing::TEST_P ( EntityTest  ,
CoverageForStrokePathWithNegativeValuesInTransform   
)

Definition at line 1935 of file entity_unittests.cc.

1935  {
1936  auto arrow_head = PathBuilder{}
1937  .MoveTo({50, 120})
1938  .LineTo({120, 190})
1939  .LineTo({190, 120})
1940  .TakePath();
1941  auto geometry = Geometry::MakeStrokePath(arrow_head, 15.0, 4.0, Cap::kRound,
1942  Join::kRound);
1943 
1944  auto transform = Matrix::MakeTranslation({300, 300}) *
1945  Matrix::MakeRotationZ(Radians(kPiOver2));
1946  // Note that e[0][0] used to be tested here, but it was -epsilon solely
1947  // due to floating point inaccuracy in the transcendental trig functions.
1948  // e[1][0] is the intended negative value that we care about (-1.0) as it
1949  // comes from the rotation of pi/2.
1950  EXPECT_LT(transform.e[1][0], 0.0f);
1951  auto coverage = geometry->GetCoverage(transform);
1952  ASSERT_RECT_NEAR(coverage.value(), Rect::MakeXYWH(102.5, 342.5, 85, 155));
1953 }

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() [366/497]

impeller::testing::TEST_P ( EntityTest  ,
CubicCurveAndOverlapTest   
)

Definition at line 415 of file entity_unittests.cc.

415  {
416  // Compare with https://fiddle.skia.org/c/7a05a3e186c65a8dfb732f68020aae06
417  Path path =
418  PathBuilder{}
419  .MoveTo({359.934, 96.6335})
420  .CubicCurveTo({358.189, 96.7055}, {356.436, 96.7908},
421  {354.673, 96.8895})
422  .CubicCurveTo({354.571, 96.8953}, {354.469, 96.9016},
423  {354.367, 96.9075})
424  .CubicCurveTo({352.672, 97.0038}, {350.969, 97.113},
425  {349.259, 97.2355})
426  .CubicCurveTo({349.048, 97.2506}, {348.836, 97.2678},
427  {348.625, 97.2834})
428  .CubicCurveTo({347.019, 97.4014}, {345.407, 97.5299},
429  {343.789, 97.6722})
430  .CubicCurveTo({343.428, 97.704}, {343.065, 97.7402},
431  {342.703, 97.7734})
432  .CubicCurveTo({341.221, 97.9086}, {339.736, 98.0505},
433  {338.246, 98.207})
434  .CubicCurveTo({337.702, 98.2642}, {337.156, 98.3292},
435  {336.612, 98.3894})
436  .CubicCurveTo({335.284, 98.5356}, {333.956, 98.6837},
437  {332.623, 98.8476})
438  .CubicCurveTo({332.495, 98.8635}, {332.366, 98.8818},
439  {332.237, 98.8982})
440  .LineTo({332.237, 102.601})
441  .LineTo({321.778, 102.601})
442  .LineTo({321.778, 100.382})
443  .CubicCurveTo({321.572, 100.413}, {321.367, 100.442},
444  {321.161, 100.476})
445  .CubicCurveTo({319.22, 100.79}, {317.277, 101.123},
446  {315.332, 101.479})
447  .CubicCurveTo({315.322, 101.481}, {315.311, 101.482},
448  {315.301, 101.484})
449  .LineTo({310.017, 105.94})
450  .LineTo({309.779, 105.427})
451  .LineTo({314.403, 101.651})
452  .CubicCurveTo({314.391, 101.653}, {314.379, 101.656},
453  {314.368, 101.658})
454  .CubicCurveTo({312.528, 102.001}, {310.687, 102.366},
455  {308.846, 102.748})
456  .CubicCurveTo({307.85, 102.955}, {306.855, 103.182}, {305.859, 103.4})
457  .CubicCurveTo({305.048, 103.579}, {304.236, 103.75},
458  {303.425, 103.936})
459  .LineTo({299.105, 107.578})
460  .LineTo({298.867, 107.065})
461  .LineTo({302.394, 104.185})
462  .LineTo({302.412, 104.171})
463  .CubicCurveTo({301.388, 104.409}, {300.366, 104.67},
464  {299.344, 104.921})
465  .CubicCurveTo({298.618, 105.1}, {297.89, 105.269}, {297.165, 105.455})
466  .CubicCurveTo({295.262, 105.94}, {293.36, 106.445},
467  {291.462, 106.979})
468  .CubicCurveTo({291.132, 107.072}, {290.802, 107.163},
469  {290.471, 107.257})
470  .CubicCurveTo({289.463, 107.544}, {288.455, 107.839},
471  {287.449, 108.139})
472  .CubicCurveTo({286.476, 108.431}, {285.506, 108.73},
473  {284.536, 109.035})
474  .CubicCurveTo({283.674, 109.304}, {282.812, 109.579},
475  {281.952, 109.859})
476  .CubicCurveTo({281.177, 110.112}, {280.406, 110.377},
477  {279.633, 110.638})
478  .CubicCurveTo({278.458, 111.037}, {277.256, 111.449},
479  {276.803, 111.607})
480  .CubicCurveTo({276.76, 111.622}, {276.716, 111.637},
481  {276.672, 111.653})
482  .CubicCurveTo({275.017, 112.239}, {273.365, 112.836},
483  {271.721, 113.463})
484  .LineTo({271.717, 113.449})
485  .CubicCurveTo({271.496, 113.496}, {271.238, 113.559},
486  {270.963, 113.628})
487  .CubicCurveTo({270.893, 113.645}, {270.822, 113.663},
488  {270.748, 113.682})
489  .CubicCurveTo({270.468, 113.755}, {270.169, 113.834},
490  {269.839, 113.926})
491  .CubicCurveTo({269.789, 113.94}, {269.732, 113.957},
492  {269.681, 113.972})
493  .CubicCurveTo({269.391, 114.053}, {269.081, 114.143},
494  {268.756, 114.239})
495  .CubicCurveTo({268.628, 114.276}, {268.5, 114.314},
496  {268.367, 114.354})
497  .CubicCurveTo({268.172, 114.412}, {267.959, 114.478},
498  {267.752, 114.54})
499  .CubicCurveTo({263.349, 115.964}, {258.058, 117.695},
500  {253.564, 119.252})
501  .CubicCurveTo({253.556, 119.255}, {253.547, 119.258},
502  {253.538, 119.261})
503  .CubicCurveTo({251.844, 119.849}, {250.056, 120.474},
504  {248.189, 121.131})
505  .CubicCurveTo({248, 121.197}, {247.812, 121.264}, {247.621, 121.331})
506  .CubicCurveTo({247.079, 121.522}, {246.531, 121.715},
507  {245.975, 121.912})
508  .CubicCurveTo({245.554, 122.06}, {245.126, 122.212},
509  {244.698, 122.364})
510  .CubicCurveTo({244.071, 122.586}, {243.437, 122.811},
511  {242.794, 123.04})
512  .CubicCurveTo({242.189, 123.255}, {241.58, 123.472},
513  {240.961, 123.693})
514  .CubicCurveTo({240.659, 123.801}, {240.357, 123.909},
515  {240.052, 124.018})
516  .CubicCurveTo({239.12, 124.351}, {238.18, 124.687}, {237.22, 125.032})
517  .LineTo({237.164, 125.003})
518  .CubicCurveTo({236.709, 125.184}, {236.262, 125.358},
519  {235.81, 125.538})
520  .CubicCurveTo({235.413, 125.68}, {234.994, 125.832},
521  {234.592, 125.977})
522  .CubicCurveTo({234.592, 125.977}, {234.591, 125.977},
523  {234.59, 125.977})
524  .CubicCurveTo({222.206, 130.435}, {207.708, 135.753},
525  {192.381, 141.429})
526  .CubicCurveTo({162.77, 151.336}, {122.17, 156.894}, {84.1123, 160})
527  .LineTo({360, 160})
528  .LineTo({360, 119.256})
529  .LineTo({360, 106.332})
530  .LineTo({360, 96.6307})
531  .CubicCurveTo({359.978, 96.6317}, {359.956, 96.6326},
532  {359.934, 96.6335})
533  .Close()
534  .MoveTo({337.336, 124.143})
535  .CubicCurveTo({337.274, 122.359}, {338.903, 121.511},
536  {338.903, 121.511})
537  .CubicCurveTo({338.903, 121.511}, {338.96, 123.303},
538  {337.336, 124.143})
539  .Close()
540  .MoveTo({340.082, 121.849})
541  .CubicCurveTo({340.074, 121.917}, {340.062, 121.992},
542  {340.046, 122.075})
543  .CubicCurveTo({340.039, 122.109}, {340.031, 122.142},
544  {340.023, 122.177})
545  .CubicCurveTo({340.005, 122.26}, {339.98, 122.346},
546  {339.952, 122.437})
547  .CubicCurveTo({339.941, 122.473}, {339.931, 122.507},
548  {339.918, 122.544})
549  .CubicCurveTo({339.873, 122.672}, {339.819, 122.804},
550  {339.75, 122.938})
551  .CubicCurveTo({339.747, 122.944}, {339.743, 122.949},
552  {339.74, 122.955})
553  .CubicCurveTo({339.674, 123.08}, {339.593, 123.205},
554  {339.501, 123.328})
555  .CubicCurveTo({339.473, 123.366}, {339.441, 123.401},
556  {339.41, 123.438})
557  .CubicCurveTo({339.332, 123.534}, {339.243, 123.625},
558  {339.145, 123.714})
559  .CubicCurveTo({339.105, 123.75}, {339.068, 123.786},
560  {339.025, 123.821})
561  .CubicCurveTo({338.881, 123.937}, {338.724, 124.048},
562  {338.539, 124.143})
563  .CubicCurveTo({338.532, 123.959}, {338.554, 123.79},
564  {338.58, 123.626})
565  .CubicCurveTo({338.58, 123.625}, {338.58, 123.625}, {338.58, 123.625})
566  .CubicCurveTo({338.607, 123.455}, {338.65, 123.299},
567  {338.704, 123.151})
568  .CubicCurveTo({338.708, 123.14}, {338.71, 123.127},
569  {338.714, 123.117})
570  .CubicCurveTo({338.769, 122.971}, {338.833, 122.838},
571  {338.905, 122.712})
572  .CubicCurveTo({338.911, 122.702}, {338.916, 122.69200000000001},
573  {338.922, 122.682})
574  .CubicCurveTo({338.996, 122.557}, {339.072, 122.444},
575  {339.155, 122.34})
576  .CubicCurveTo({339.161, 122.333}, {339.166, 122.326},
577  {339.172, 122.319})
578  .CubicCurveTo({339.256, 122.215}, {339.339, 122.12},
579  {339.425, 122.037})
580  .CubicCurveTo({339.428, 122.033}, {339.431, 122.03},
581  {339.435, 122.027})
582  .CubicCurveTo({339.785, 121.687}, {340.106, 121.511},
583  {340.106, 121.511})
584  .CubicCurveTo({340.106, 121.511}, {340.107, 121.645},
585  {340.082, 121.849})
586  .Close()
587  .MoveTo({340.678, 113.245})
588  .CubicCurveTo({340.594, 113.488}, {340.356, 113.655},
589  {340.135, 113.775})
590  .CubicCurveTo({339.817, 113.948}, {339.465, 114.059},
591  {339.115, 114.151})
592  .CubicCurveTo({338.251, 114.379}, {337.34, 114.516},
593  {336.448, 114.516})
594  .CubicCurveTo({335.761, 114.516}, {335.072, 114.527},
595  {334.384, 114.513})
596  .CubicCurveTo({334.125, 114.508}, {333.862, 114.462},
597  {333.605, 114.424})
598  .CubicCurveTo({332.865, 114.318}, {332.096, 114.184},
599  {331.41, 113.883})
600  .CubicCurveTo({330.979, 113.695}, {330.442, 113.34},
601  {330.672, 112.813})
602  .CubicCurveTo({331.135, 111.755}, {333.219, 112.946},
603  {334.526, 113.833})
604  .CubicCurveTo({334.54, 113.816}, {334.554, 113.8}, {334.569, 113.784})
605  .CubicCurveTo({333.38, 112.708}, {331.749, 110.985},
606  {332.76, 110.402})
607  .CubicCurveTo({333.769, 109.82}, {334.713, 111.93},
608  {335.228, 113.395})
609  .CubicCurveTo({334.915, 111.889}, {334.59, 109.636},
610  {335.661, 109.592})
611  .CubicCurveTo({336.733, 109.636}, {336.408, 111.889},
612  {336.07, 113.389})
613  .CubicCurveTo({336.609, 111.93}, {337.553, 109.82},
614  {338.563, 110.402})
615  .CubicCurveTo({339.574, 110.984}, {337.942, 112.708},
616  {336.753, 113.784})
617  .CubicCurveTo({336.768, 113.8}, {336.782, 113.816},
618  {336.796, 113.833})
619  .CubicCurveTo({338.104, 112.946}, {340.187, 111.755},
620  {340.65, 112.813})
621  .CubicCurveTo({340.71, 112.95}, {340.728, 113.102},
622  {340.678, 113.245})
623  .Close()
624  .MoveTo({346.357, 106.771})
625  .CubicCurveTo({346.295, 104.987}, {347.924, 104.139},
626  {347.924, 104.139})
627  .CubicCurveTo({347.924, 104.139}, {347.982, 105.931},
628  {346.357, 106.771})
629  .Close()
630  .MoveTo({347.56, 106.771})
631  .CubicCurveTo({347.498, 104.987}, {349.127, 104.139},
632  {349.127, 104.139})
633  .CubicCurveTo({349.127, 104.139}, {349.185, 105.931},
634  {347.56, 106.771})
635  .Close()
636  .TakePath();
637  Entity entity;
638  entity.SetTransform(Matrix::MakeScale(GetContentScale()));
639 
640  std::unique_ptr<Geometry> geom = Geometry::MakeFillPath(path);
641 
642  auto contents = std::make_shared<SolidColorContents>();
643  contents->SetColor(Color::Red());
644  contents->SetGeometry(geom.get());
645 
646  entity.SetContents(contents);
647  ASSERT_TRUE(OpenPlaygroundHere(std::move(entity)));
648 }

References impeller::Close(), impeller::LineTo(), impeller::Geometry::MakeFillPath(), impeller::Matrix::MakeScale(), impeller::PathBuilder::MoveTo(), impeller::Color::Red(), impeller::Entity::SetContents(), and impeller::Entity::SetTransform().

◆ TEST_P() [367/497]

impeller::testing::TEST_P ( EntityTest  ,
CubicCurveTest   
)

Definition at line 333 of file entity_unittests.cc.

333  {
334  // Compare with https://fiddle.skia.org/c/b3625f26122c9de7afe7794fcf25ead3
335  Path path =
336  PathBuilder{}
337  .MoveTo({237.164, 125.003})
338  .CubicCurveTo({236.709, 125.184}, {236.262, 125.358},
339  {235.81, 125.538})
340  .CubicCurveTo({235.413, 125.68}, {234.994, 125.832},
341  {234.592, 125.977})
342  .CubicCurveTo({234.592, 125.977}, {234.591, 125.977},
343  {234.59, 125.977})
344  .CubicCurveTo({222.206, 130.435}, {207.708, 135.753},
345  {192.381, 141.429})
346  .CubicCurveTo({162.77, 151.336}, {122.17, 156.894}, {84.1123, 160})
347  .Close()
348  .TakePath();
349  Entity entity;
350  entity.SetTransform(Matrix::MakeScale(GetContentScale()));
351 
352  std::unique_ptr<Geometry> geom = Geometry::MakeFillPath(path);
353 
354  auto contents = std::make_shared<SolidColorContents>();
355  contents->SetColor(Color::Red());
356  contents->SetGeometry(geom.get());
357 
358  entity.SetContents(contents);
359  ASSERT_TRUE(OpenPlaygroundHere(std::move(entity)));
360 }

References impeller::Close(), impeller::Geometry::MakeFillPath(), impeller::Matrix::MakeScale(), impeller::PathBuilder::MoveTo(), impeller::Color::Red(), impeller::Entity::SetContents(), and impeller::Entity::SetTransform().

◆ TEST_P() [368/497]

impeller::testing::TEST_P ( EntityTest  ,
DecalSpecializationAppliedToMorphologyFilter   
)

Definition at line 2139 of file entity_unittests.cc.

2139  {
2140  auto content_context = GetContentContext();
2141  auto default_color_burn = content_context->GetMorphologyFilterPipeline({
2142  .color_attachment_pixel_format = PixelFormat::kR8G8B8A8UNormInt,
2143  });
2144 
2145  auto decal_supported = static_cast<Scalar>(
2146  GetContext()->GetCapabilities()->SupportsDecalSamplerAddressMode());
2147  std::vector<Scalar> expected_constants = {decal_supported};
2148  ASSERT_EQ(default_color_burn->GetDescriptor().GetSpecializationConstants(),
2149  expected_constants);
2150 }

References impeller::kR8G8B8A8UNormInt.

◆ TEST_P() [369/497]

impeller::testing::TEST_P ( EntityTest  ,
DrawRoundSuperEllipse   
)

Definition at line 2321 of file entity_unittests.cc.

2321  {
2322  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
2323  // UI state.
2324  static float center[2] = {830, 830};
2325  static float size[2] = {600, 600};
2326  static bool horizontal_symmetry = true;
2327  static bool vertical_symmetry = true;
2328  static bool corner_symmetry = true;
2329 
2330  // Initially radius_tl[0] will be mirrored to all 8 values since all 3
2331  // symmetries are enabled.
2332  static std::array<float, 2> radius_tl = {200};
2333  static std::array<float, 2> radius_tr;
2334  static std::array<float, 2> radius_bl;
2335  static std::array<float, 2> radius_br;
2336 
2337  auto AddRadiusControl = [](std::array<float, 2>& radii, const char* tb_name,
2338  const char* lr_name) {
2339  std::string name = "Radius";
2340  if (!horizontal_symmetry || !vertical_symmetry) {
2341  name += ":";
2342  }
2343  if (!vertical_symmetry) {
2344  name = name + " " + tb_name;
2345  }
2346  if (!horizontal_symmetry) {
2347  name = name + " " + lr_name;
2348  }
2349  if (corner_symmetry) {
2350  ImGui::SliderFloat(name.c_str(), radii.data(), 0, 1000);
2351  } else {
2352  ImGui::SliderFloat2(name.c_str(), radii.data(), 0, 1000);
2353  }
2354  };
2355 
2356  if (corner_symmetry) {
2357  radius_tl[1] = radius_tl[0];
2358  radius_tr[1] = radius_tr[0];
2359  radius_bl[1] = radius_bl[0];
2360  radius_br[1] = radius_br[0];
2361  }
2362 
2363  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
2364  {
2365  ImGui::SliderFloat2("Center", center, 0, 1000);
2366  ImGui::SliderFloat2("Size", size, 0, 1000);
2367  ImGui::Checkbox("Symmetry: Horizontal", &horizontal_symmetry);
2368  ImGui::Checkbox("Symmetry: Vertical", &vertical_symmetry);
2369  ImGui::Checkbox("Symmetry: Corners", &corner_symmetry);
2370  AddRadiusControl(radius_tl, "Top", "Left");
2371  if (!horizontal_symmetry) {
2372  AddRadiusControl(radius_tr, "Top", "Right");
2373  } else {
2374  radius_tr = radius_tl;
2375  }
2376  if (!vertical_symmetry) {
2377  AddRadiusControl(radius_bl, "Bottom", "Left");
2378  } else {
2379  radius_bl = radius_tl;
2380  }
2381  if (!horizontal_symmetry && !vertical_symmetry) {
2382  AddRadiusControl(radius_br, "Bottom", "Right");
2383  } else {
2384  if (horizontal_symmetry) {
2385  radius_br = radius_bl;
2386  } else {
2387  radius_br = radius_tr;
2388  }
2389  }
2390  }
2391 
2392  ImGui::End();
2393 
2394  RoundingRadii radii{
2395  .top_left = {radius_tl[0], radius_tl[1]},
2396  .top_right = {radius_tr[0], radius_tr[1]},
2397  .bottom_left = {radius_bl[0], radius_bl[1]},
2398  .bottom_right = {radius_br[0], radius_br[1]},
2399  };
2400 
2401  auto contents = std::make_shared<SolidColorContents>();
2402  std::unique_ptr<RoundSuperellipseGeometry> geom =
2403  std::make_unique<RoundSuperellipseGeometry>(
2404  Rect::MakeOriginSize({center[0], center[1]}, {size[0], size[1]}),
2405  radii);
2406  contents->SetColor(Color::Red());
2407  contents->SetGeometry(geom.get());
2408 
2409  Entity entity;
2410  entity.SetContents(contents);
2411 
2412  return entity.Render(context, pass);
2413  };
2414 
2415  ASSERT_TRUE(OpenPlaygroundHere(callback));
2416 }

References impeller::TRect< Scalar >::MakeOriginSize(), impeller::Color::Red(), impeller::Entity::Render(), impeller::Entity::SetContents(), and impeller::RoundingRadii::top_left.

◆ TEST_P() [370/497]

impeller::testing::TEST_P ( EntityTest  ,
DrawSuperEllipse   
)

Definition at line 2288 of file entity_unittests.cc.

2288  {
2289  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
2290  // UI state.
2291  static float alpha = 10;
2292  static float beta = 10;
2293  static float radius = 40;
2294  static int degree = 4;
2295  static Color color = Color::Red();
2296 
2297  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
2298  ImGui::SliderFloat("Alpha", &alpha, 0, 100);
2299  ImGui::SliderFloat("Beta", &beta, 0, 100);
2300  ImGui::SliderInt("Degreee", &degree, 1, 20);
2301  ImGui::SliderFloat("Radius", &radius, 0, 400);
2302  ImGui::ColorEdit4("Color", reinterpret_cast<float*>(&color));
2303  ImGui::End();
2304 
2305  auto contents = std::make_shared<SolidColorContents>();
2306  std::unique_ptr<SuperellipseGeometry> geom =
2307  std::make_unique<SuperellipseGeometry>(Point{400, 400}, radius, degree,
2308  alpha, beta);
2309  contents->SetColor(color);
2310  contents->SetGeometry(geom.get());
2311 
2312  Entity entity;
2313  entity.SetContents(contents);
2314 
2315  return entity.Render(context, pass);
2316  };
2317 
2318  ASSERT_TRUE(OpenPlaygroundHere(callback));
2319 }

References impeller::Color::Red(), impeller::Entity::Render(), and impeller::Entity::SetContents().

◆ TEST_P() [371/497]

impeller::testing::TEST_P ( EntityTest  ,
FailOnValidationError   
)

Definition at line 2233 of file entity_unittests.cc.

2233  {
2234  if (GetParam() != PlaygroundBackend::kVulkan) {
2235  GTEST_SKIP() << "Validation is only fatal on Vulkan backend.";
2236  }
2237  EXPECT_DEATH(
2238  // The easiest way to trigger a validation error is to try to compile
2239  // a shader with an unsupported pixel format.
2240  GetContentContext()->GetBlendColorBurnPipeline({
2241  .color_attachment_pixel_format = PixelFormat::kUnknown,
2242  .has_depth_stencil_attachments = false,
2243  }),
2244  "");
2245 }

References impeller::kUnknown, and impeller::kVulkan.

◆ TEST_P() [372/497]

impeller::testing::TEST_P ( EntityTest  ,
FillPathGeometryGetPositionBufferReturnsExpectedMode   
)

Definition at line 2199 of file entity_unittests.cc.

2199  {
2200  RenderTarget target;
2201  testing::MockRenderPass mock_pass(GetContext(), target);
2202 
2203  auto get_result = [this, &mock_pass](const Path& path) {
2204  auto geometry = Geometry::MakeFillPath(
2205  path, /* inner rect */ Rect::MakeLTRB(0, 0, 100, 100));
2206  return geometry->GetPositionBuffer(*GetContentContext(), {}, mock_pass);
2207  };
2208 
2209  // Convex path
2210  {
2211  GeometryResult result =
2212  get_result(PathBuilder{}
2213  .AddRect(Rect::MakeLTRB(0, 0, 100, 100))
2214  .SetConvexity(Convexity::kConvex)
2215  .TakePath());
2216  EXPECT_EQ(result.mode, GeometryResult::Mode::kNormal);
2217  }
2218 
2219  // Concave path
2220  {
2221  Path path = PathBuilder{}
2222  .MoveTo({0, 0})
2223  .LineTo({100, 0})
2224  .LineTo({100, 100})
2225  .LineTo({50, 50})
2226  .Close()
2227  .TakePath();
2228  GeometryResult result = get_result(path);
2229  EXPECT_EQ(result.mode, GeometryResult::Mode::kNonZero);
2230  }
2231 }

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() [373/497]

impeller::testing::TEST_P ( EntityTest  ,
FilterCoverageRespectsCropRect   
)

Definition at line 73 of file entity_unittests.cc.

73  {
74  auto image = CreateTextureForFixture("boston.jpg");
75  auto filter = ColorFilterContents::MakeBlend(BlendMode::kSoftLight,
76  FilterInput::Make({image}));
77 
78  // Without the crop rect (default behavior).
79  {
80  auto actual = filter->GetCoverage({});
81  auto expected = Rect::MakeSize(image->GetSize());
82 
83  ASSERT_TRUE(actual.has_value());
84  ASSERT_RECT_NEAR(actual.value(), expected);
85  }
86 
87  // With the crop rect.
88  {
89  auto expected = Rect::MakeLTRB(50, 50, 100, 100);
90  filter->SetCoverageHint(expected);
91  auto actual = filter->GetCoverage({});
92 
93  ASSERT_TRUE(actual.has_value());
94  ASSERT_RECT_NEAR(actual.value(), expected);
95  }
96 }

References ASSERT_RECT_NEAR, impeller::kSoftLight, impeller::FilterInput::Make(), impeller::ColorFilterContents::MakeBlend(), impeller::TRect< Scalar >::MakeLTRB(), and impeller::TRect< Scalar >::MakeSize().

◆ TEST_P() [374/497]

impeller::testing::TEST_P ( EntityTest  ,
Filters   
)

Definition at line 866 of file entity_unittests.cc.

866  {
867  auto bridge = CreateTextureForFixture("bay_bridge.jpg");
868  auto boston = CreateTextureForFixture("boston.jpg");
869  auto kalimba = CreateTextureForFixture("kalimba.jpg");
870  ASSERT_TRUE(bridge && boston && kalimba);
871 
872  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
873  auto fi_bridge = FilterInput::Make(bridge);
874  auto fi_boston = FilterInput::Make(boston);
875  auto fi_kalimba = FilterInput::Make(kalimba);
876 
877  std::shared_ptr<FilterContents> blend0 = ColorFilterContents::MakeBlend(
878  BlendMode::kModulate, {fi_kalimba, fi_boston});
879 
880  auto blend1 = ColorFilterContents::MakeBlend(
881  BlendMode::kScreen,
882  {FilterInput::Make(blend0), fi_bridge, fi_bridge, fi_bridge});
883 
884  Entity entity;
885  entity.SetTransform(Matrix::MakeScale(GetContentScale()) *
886  Matrix::MakeTranslation({500, 300}) *
887  Matrix::MakeScale(Vector2{0.5, 0.5}));
888  entity.SetContents(blend1);
889  return entity.Render(context, pass);
890  };
891  ASSERT_TRUE(OpenPlaygroundHere(callback));
892 }

References impeller::kModulate, impeller::kScreen, impeller::FilterInput::Make(), impeller::ColorFilterContents::MakeBlend(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeTranslation(), and impeller::Entity::SetTransform().

◆ TEST_P() [375/497]

impeller::testing::TEST_P ( EntityTest  ,
GaussianBlurFilter   
)

Definition at line 894 of file entity_unittests.cc.

894  {
895  auto boston =
896  CreateTextureForFixture("boston.jpg", /*enable_mipmapping=*/true);
897  ASSERT_TRUE(boston);
898 
899  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
900  const char* input_type_names[] = {"Texture", "Solid Color"};
901  const char* blur_type_names[] = {"Image blur", "Mask blur"};
902  const char* pass_variation_names[] = {"New"};
903  const char* blur_style_names[] = {"Normal", "Solid", "Outer", "Inner"};
904  const char* tile_mode_names[] = {"Clamp", "Repeat", "Mirror", "Decal"};
905  const FilterContents::BlurStyle blur_styles[] = {
906  FilterContents::BlurStyle::kNormal, FilterContents::BlurStyle::kSolid,
907  FilterContents::BlurStyle::kOuter, FilterContents::BlurStyle::kInner};
908  const Entity::TileMode tile_modes[] = {
909  Entity::TileMode::kClamp, Entity::TileMode::kRepeat,
910  Entity::TileMode::kMirror, Entity::TileMode::kDecal};
911 
912  // UI state.
913  static int selected_input_type = 0;
914  static Color input_color = Color::Black();
915  static int selected_blur_type = 0;
916  static int selected_pass_variation = 0;
917  static bool combined_sigma = false;
918  static float blur_amount_coarse[2] = {0, 0};
919  static float blur_amount_fine[2] = {10, 10};
920  static int selected_blur_style = 0;
921  static int selected_tile_mode = 3;
922  static Color cover_color(1, 0, 0, 0.2);
923  static Color bounds_color(0, 1, 0, 0.1);
924  static float offset[2] = {500, 400};
925  static float rotation = 0;
926  static float scale[2] = {0.65, 0.65};
927  static float skew[2] = {0, 0};
928  static float path_rect[4] = {0, 0,
929  static_cast<float>(boston->GetSize().width),
930  static_cast<float>(boston->GetSize().height)};
931 
932  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
933  {
934  ImGui::Combo("Input type", &selected_input_type, input_type_names,
935  sizeof(input_type_names) / sizeof(char*));
936  if (selected_input_type == 0) {
937  ImGui::SliderFloat("Input opacity", &input_color.alpha, 0, 1);
938  } else {
939  ImGui::ColorEdit4("Input color",
940  reinterpret_cast<float*>(&input_color));
941  }
942  ImGui::Combo("Blur type", &selected_blur_type, blur_type_names,
943  sizeof(blur_type_names) / sizeof(char*));
944  if (selected_blur_type == 0) {
945  ImGui::Combo("Pass variation", &selected_pass_variation,
946  pass_variation_names,
947  sizeof(pass_variation_names) / sizeof(char*));
948  }
949  ImGui::Checkbox("Combined sigma", &combined_sigma);
950  if (combined_sigma) {
951  ImGui::SliderFloat("Sigma (coarse)", blur_amount_coarse, 0, 1000);
952  ImGui::SliderFloat("Sigma (fine)", blur_amount_fine, 0, 10);
953  blur_amount_coarse[1] = blur_amount_coarse[0];
954  blur_amount_fine[1] = blur_amount_fine[0];
955  } else {
956  ImGui::SliderFloat2("Sigma (coarse)", blur_amount_coarse, 0, 1000);
957  ImGui::SliderFloat2("Sigma (fine)", blur_amount_fine, 0, 10);
958  }
959  ImGui::Combo("Blur style", &selected_blur_style, blur_style_names,
960  sizeof(blur_style_names) / sizeof(char*));
961  ImGui::Combo("Tile mode", &selected_tile_mode, tile_mode_names,
962  sizeof(tile_mode_names) / sizeof(char*));
963  ImGui::ColorEdit4("Cover color", reinterpret_cast<float*>(&cover_color));
964  ImGui::ColorEdit4("Bounds color ",
965  reinterpret_cast<float*>(&bounds_color));
966  ImGui::SliderFloat2("Translation", offset, 0,
967  pass.GetRenderTargetSize().width);
968  ImGui::SliderFloat("Rotation", &rotation, 0, kPi * 2);
969  ImGui::SliderFloat2("Scale", scale, 0, 3);
970  ImGui::SliderFloat2("Skew", skew, -3, 3);
971  ImGui::SliderFloat4("Path XYWH", path_rect, -1000, 1000);
972  }
973  ImGui::End();
974 
975  auto blur_sigma_x = Sigma{blur_amount_coarse[0] + blur_amount_fine[0]};
976  auto blur_sigma_y = Sigma{blur_amount_coarse[1] + blur_amount_fine[1]};
977 
978  std::shared_ptr<Contents> input;
979  Size input_size;
980 
981  auto input_rect =
982  Rect::MakeXYWH(path_rect[0], path_rect[1], path_rect[2], path_rect[3]);
983 
984  std::unique_ptr<Geometry> solid_color_input;
985  if (selected_input_type == 0) {
986  auto texture = std::make_shared<TextureContents>();
987  texture->SetSourceRect(Rect::MakeSize(boston->GetSize()));
988  texture->SetDestinationRect(input_rect);
989  texture->SetTexture(boston);
990  texture->SetOpacity(input_color.alpha);
991 
992  input = texture;
993  input_size = input_rect.GetSize();
994  } else {
995  auto fill = std::make_shared<SolidColorContents>();
996  fill->SetColor(input_color);
997  solid_color_input =
998  Geometry::MakeFillPath(PathBuilder{}.AddRect(input_rect).TakePath());
999 
1000  fill->SetGeometry(solid_color_input.get());
1001 
1002  input = fill;
1003  input_size = input_rect.GetSize();
1004  }
1005 
1006  std::shared_ptr<FilterContents> blur;
1007  switch (selected_pass_variation) {
1008  case 0:
1009  blur = std::make_shared<GaussianBlurFilterContents>(
1010  blur_sigma_x.sigma, blur_sigma_y.sigma,
1011  tile_modes[selected_tile_mode], blur_styles[selected_blur_style],
1012  /*geometry=*/nullptr);
1013  blur->SetInputs({FilterInput::Make(input)});
1014  break;
1015  case 1:
1016  blur = FilterContents::MakeGaussianBlur(
1017  FilterInput::Make(input), blur_sigma_x, blur_sigma_y,
1018  tile_modes[selected_tile_mode], blur_styles[selected_blur_style]);
1019  break;
1020  };
1021  FML_CHECK(blur);
1022 
1023  auto mask_blur = FilterContents::MakeBorderMaskBlur(
1024  FilterInput::Make(input), blur_sigma_x, blur_sigma_y,
1025  blur_styles[selected_blur_style]);
1026 
1027  auto ctm = Matrix::MakeScale(GetContentScale()) *
1028  Matrix::MakeTranslation(Vector3(offset[0], offset[1])) *
1029  Matrix::MakeRotationZ(Radians(rotation)) *
1030  Matrix::MakeScale(Vector2(scale[0], scale[1])) *
1031  Matrix::MakeSkew(skew[0], skew[1]) *
1032  Matrix::MakeTranslation(-Point(input_size) / 2);
1033 
1034  auto target_contents = selected_blur_type == 0 ? blur : mask_blur;
1035 
1036  Entity entity;
1037  entity.SetContents(target_contents);
1038  entity.SetTransform(ctm);
1039 
1040  entity.Render(context, pass);
1041 
1042  // Renders a red "cover" rectangle that shows the original position of the
1043  // unfiltered input.
1044  Entity cover_entity;
1045  std::unique_ptr<Geometry> geom =
1046  Geometry::MakeFillPath(PathBuilder{}.AddRect(input_rect).TakePath());
1047  auto contents = std::make_shared<SolidColorContents>();
1048  contents->SetColor(cover_color);
1049  contents->SetGeometry(geom.get());
1050  cover_entity.SetContents(std::move(contents));
1051  cover_entity.SetTransform(ctm);
1052  cover_entity.Render(context, pass);
1053 
1054  // Renders a green bounding rect of the target filter.
1055  Entity bounds_entity;
1056  std::optional<Rect> target_contents_coverage =
1057  target_contents->GetCoverage(entity);
1058  if (target_contents_coverage.has_value()) {
1059  std::unique_ptr<Geometry> geom = Geometry::MakeFillPath(
1060  PathBuilder{}
1061  .AddRect(target_contents->GetCoverage(entity).value())
1062  .TakePath());
1063  auto contents = std::make_shared<SolidColorContents>();
1064  contents->SetColor(bounds_color);
1065  contents->SetGeometry(geom.get());
1066 
1067  bounds_entity.SetContents(contents);
1068  bounds_entity.SetTransform(Matrix());
1069  bounds_entity.Render(context, pass);
1070  }
1071 
1072  return true;
1073  };
1074  ASSERT_TRUE(OpenPlaygroundHere(callback));
1075 }

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::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() [376/497]

impeller::testing::TEST_P ( EntityTest  ,
GeometryBoundsAreTransformed   
)

Definition at line 98 of file entity_unittests.cc.

98  {
99  auto geometry = Geometry::MakeRect(Rect::MakeXYWH(100, 100, 100, 100));
100  auto transform = Matrix::MakeScale({2.0, 2.0, 2.0});
101 
102  ASSERT_RECT_NEAR(geometry->GetCoverage(transform).value(),
103  Rect::MakeXYWH(200, 200, 200, 200));
104 }

References ASSERT_RECT_NEAR, impeller::Geometry::MakeRect(), impeller::Matrix::MakeScale(), impeller::TRect< Scalar >::MakeXYWH(), and transform.

◆ TEST_P() [377/497]

impeller::testing::TEST_P ( EntityTest  ,
GiantLineStripPathAllocation   
)

Definition at line 2508 of file entity_unittests.cc.

2508  {
2509  PathBuilder builder{};
2510  for (int i = 0; i < 10000; i++) {
2511  builder.LineTo(Point(i, i));
2512  }
2513  Path path = builder.TakePath();
2514 
2515  ContentContext content_context(GetContext(), /*typographer_context=*/nullptr);
2516  Entity entity;
2517 
2518  auto host_buffer = HostBuffer::Create(GetContext()->GetResourceAllocator(),
2519  GetContext()->GetIdleWaiter());
2520  auto tessellator = Tessellator();
2521 
2522  auto vertex_buffer = tessellator.GenerateLineStrip(path, *host_buffer, 1.0);
2523 
2524  // Validate the buffer data overflowed the small buffer
2525  EXPECT_GT(vertex_buffer.vertex_count, kPointArenaSize);
2526 
2527  // Validate that there are no uninitialized points near the gap.
2528  Point* written_data = reinterpret_cast<Point*>(
2529  (vertex_buffer.vertex_buffer.GetBuffer()->OnGetContents() +
2530  vertex_buffer.vertex_buffer.GetRange().offset));
2531 
2532  std::vector<Point> expected = {
2533  Point(4093, 4093), //
2534  Point(4094, 4094), //
2535  Point(4095, 4095), //
2536  Point(4096, 4096), //
2537  Point(4097, 4097) //
2538  };
2539 
2540  Point point = written_data[kPointArenaSize - 2];
2541  EXPECT_NEAR(point.x, expected[0].x, 0.1);
2542  EXPECT_NEAR(point.y, expected[0].y, 0.1);
2543 
2544  point = written_data[kPointArenaSize - 1];
2545  EXPECT_NEAR(point.x, expected[1].x, 0.1);
2546  EXPECT_NEAR(point.y, expected[1].y, 0.1);
2547 
2548  point = written_data[kPointArenaSize];
2549  EXPECT_NEAR(point.x, expected[2].x, 0.1);
2550  EXPECT_NEAR(point.y, expected[2].y, 0.1);
2551 
2552  point = written_data[kPointArenaSize + 1];
2553  EXPECT_NEAR(point.x, expected[3].x, 0.1);
2554  EXPECT_NEAR(point.y, expected[3].y, 0.1);
2555 
2556  point = written_data[kPointArenaSize + 2];
2557  EXPECT_NEAR(point.x, expected[4].x, 0.1);
2558  EXPECT_NEAR(point.y, expected[4].y, 0.1);
2559 }
static constexpr size_t kPointArenaSize
The size of the point arena buffer stored on the tessellator.
Definition: tessellator.h:22

References impeller::HostBuffer::Create(), impeller::kPointArenaSize, impeller::PathBuilder::LineTo(), impeller::TPoint< T >::x, and impeller::TPoint< T >::y.

◆ TEST_P() [378/497]

impeller::testing::TEST_P ( EntityTest  ,
GiantStrokePathAllocation   
)

Definition at line 2448 of file entity_unittests.cc.

2448  {
2449  PathBuilder builder{};
2450  for (int i = 0; i < 10000; i++) {
2451  builder.LineTo(Point(i, i));
2452  }
2453  Path path = builder.TakePath();
2454  auto geom = Geometry::MakeStrokePath(path, /*stroke_width=*/10);
2455 
2456  ContentContext content_context(GetContext(), /*typographer_context=*/nullptr);
2457  Entity entity;
2458 
2459  auto cmd_buffer = content_context.GetContext()->CreateCommandBuffer();
2460 
2461  RenderTargetAllocator allocator(
2462  content_context.GetContext()->GetResourceAllocator());
2463 
2464  auto render_target = allocator.CreateOffscreen(
2465  *content_context.GetContext(), /*size=*/{10, 10}, /*mip_count=*/1);
2466  auto pass = cmd_buffer->CreateRenderPass(render_target);
2467 
2468  GeometryResult result =
2469  geom->GetPositionBuffer(content_context, entity, *pass);
2470 
2471  // Validate the buffer data overflowed the small buffer
2472  EXPECT_GT(result.vertex_buffer.vertex_count, kPointArenaSize);
2473 
2474  // Validate that there are no uninitialized points near the gap.
2475  Point* written_data = reinterpret_cast<Point*>(
2476  (result.vertex_buffer.vertex_buffer.GetBuffer()->OnGetContents() +
2477  result.vertex_buffer.vertex_buffer.GetRange().offset));
2478 
2479  std::vector<Point> expected = {
2480  Point(1019.46, 1026.54), //
2481  Point(1026.54, 1019.46), //
2482  Point(1020.45, 1027.54), //
2483  Point(1027.54, 1020.46), //
2484  Point(1020.46, 1027.53) //
2485  };
2486 
2487  Point point = written_data[kPointArenaSize - 2];
2488  EXPECT_NEAR(point.x, expected[0].x, 0.1);
2489  EXPECT_NEAR(point.y, expected[0].y, 0.1);
2490 
2491  point = written_data[kPointArenaSize - 1];
2492  EXPECT_NEAR(point.x, expected[1].x, 0.1);
2493  EXPECT_NEAR(point.y, expected[1].y, 0.1);
2494 
2495  point = written_data[kPointArenaSize];
2496  EXPECT_NEAR(point.x, expected[2].x, 0.1);
2497  EXPECT_NEAR(point.y, expected[2].y, 0.1);
2498 
2499  point = written_data[kPointArenaSize + 1];
2500  EXPECT_NEAR(point.x, expected[3].x, 0.1);
2501  EXPECT_NEAR(point.y, expected[3].y, 0.1);
2502 
2503  point = written_data[kPointArenaSize + 2];
2504  EXPECT_NEAR(point.x, expected[4].x, 0.1);
2505  EXPECT_NEAR(point.y, expected[4].y, 0.1);
2506 }

References impeller::RenderTargetAllocator::CreateOffscreen(), impeller::BufferView::GetBuffer(), impeller::ContentContext::GetContext(), impeller::BufferView::GetRange(), impeller::kPointArenaSize, impeller::PathBuilder::LineTo(), impeller::Geometry::MakeStrokePath(), impeller::Range::offset, impeller::DeviceBuffer::OnGetContents(), impeller::VertexBuffer::vertex_buffer, impeller::GeometryResult::vertex_buffer, impeller::VertexBuffer::vertex_count, impeller::TPoint< T >::x, and impeller::TPoint< T >::y.

◆ TEST_P() [379/497]

impeller::testing::TEST_P ( EntityTest  ,
LinearGradientContentsIsOpaque   
)

Definition at line 1997 of file entity_unittests.cc.

1997  {
1998  Matrix matrix;
1999  LinearGradientContents contents;
2000  auto geom = Geometry::MakeRect(Rect::MakeLTRB(0, 0, 10, 10));
2001  contents.SetGeometry(geom.get());
2002 
2003  contents.SetColors({Color::CornflowerBlue()});
2004  EXPECT_TRUE(contents.IsOpaque(matrix));
2005  contents.SetColors({Color::CornflowerBlue().WithAlpha(0.5)});
2006  EXPECT_FALSE(contents.IsOpaque(matrix));
2007  contents.SetColors({Color::CornflowerBlue()});
2008  contents.SetTileMode(Entity::TileMode::kDecal);
2009  EXPECT_FALSE(contents.IsOpaque(matrix));
2010 
2011  // Create stroked path that required alpha coverage.
2012  geom = Geometry::MakeStrokePath(
2013  PathBuilder{}.AddLine({0, 0}, {100, 100}).TakePath(),
2014  /*stroke_width=*/0.05);
2015  contents.SetGeometry(geom.get());
2016  contents.SetColors({Color::CornflowerBlue()});
2017 
2018  EXPECT_FALSE(contents.IsOpaque(matrix));
2019 }

References impeller::PathBuilder::AddLine(), impeller::Color::CornflowerBlue(), impeller::LinearGradientContents::IsOpaque(), impeller::Entity::kDecal, impeller::TRect< Scalar >::MakeLTRB(), impeller::Geometry::MakeRect(), impeller::Geometry::MakeStrokePath(), impeller::LinearGradientContents::SetColors(), impeller::ColorSourceContents::SetGeometry(), impeller::LinearGradientContents::SetTileMode(), and impeller::Color::WithAlpha().

◆ TEST_P() [380/497]

impeller::testing::TEST_P ( EntityTest  ,
LinearToSrgbFilter   
)

Definition at line 1491 of file entity_unittests.cc.

1491  {
1492  auto image = CreateTextureForFixture("kalimba.jpg");
1493  ASSERT_TRUE(image);
1494 
1495  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
1496  auto filtered =
1497  ColorFilterContents::MakeLinearToSrgbFilter(FilterInput::Make(image));
1498 
1499  // Define the entity that will serve as the control image as a Gaussian blur
1500  // filter with no filter at all.
1501  Entity entity_left;
1502  entity_left.SetTransform(Matrix::MakeScale(GetContentScale()) *
1503  Matrix::MakeTranslation({100, 300}) *
1504  Matrix::MakeScale(Vector2{0.5, 0.5}));
1505  auto unfiltered = FilterContents::MakeGaussianBlur(FilterInput::Make(image),
1506  Sigma{0}, Sigma{0});
1507  entity_left.SetContents(unfiltered);
1508 
1509  // Define the entity that will be filtered from linear to sRGB.
1510  Entity entity_right;
1511  entity_right.SetTransform(Matrix::MakeScale(GetContentScale()) *
1512  Matrix::MakeTranslation({500, 300}) *
1513  Matrix::MakeScale(Vector2{0.5, 0.5}));
1514  entity_right.SetContents(filtered);
1515  return entity_left.Render(context, pass) &&
1516  entity_right.Render(context, pass);
1517  };
1518 
1519  ASSERT_TRUE(OpenPlaygroundHere(callback));
1520 }

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() [381/497]

impeller::testing::TEST_P ( EntityTest  ,
LinearToSrgbFilterCoverageIsCorrect   
)

Definition at line 1469 of file entity_unittests.cc.

1469  {
1470  // Set up a simple color background.
1471  auto geom = Geometry::MakeFillPath(
1472  PathBuilder{}.AddRect(Rect::MakeXYWH(0, 0, 300, 400)).TakePath());
1473  auto fill = std::make_shared<SolidColorContents>();
1474  fill->SetGeometry(geom.get());
1475  fill->SetColor(Color::MintCream());
1476 
1477  auto filter =
1478  ColorFilterContents::MakeLinearToSrgbFilter(FilterInput::Make(fill));
1479 
1480  Entity e;
1481  e.SetTransform(Matrix());
1482 
1483  // Confirm that the actual filter coverage matches the expected coverage.
1484  auto actual = filter->GetCoverage(e);
1485  auto expected = Rect::MakeXYWH(0, 0, 300, 400);
1486 
1487  ASSERT_TRUE(actual.has_value());
1488  ASSERT_RECT_NEAR(actual.value(), expected);
1489 }

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() [382/497]

impeller::testing::TEST_P ( EntityTest  ,
MorphologyFilter   
)

Definition at line 1077 of file entity_unittests.cc.

1077  {
1078  auto boston = CreateTextureForFixture("boston.jpg");
1079  ASSERT_TRUE(boston);
1080 
1081  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
1082  const char* morphology_type_names[] = {"Dilate", "Erode"};
1083  const FilterContents::MorphType morphology_types[] = {
1084  FilterContents::MorphType::kDilate, FilterContents::MorphType::kErode};
1085  static Color input_color = Color::Black();
1086  // UI state.
1087  static int selected_morphology_type = 0;
1088  static float radius[2] = {20, 20};
1089  static Color cover_color(1, 0, 0, 0.2);
1090  static Color bounds_color(0, 1, 0, 0.1);
1091  static float offset[2] = {500, 400};
1092  static float rotation = 0;
1093  static float scale[2] = {0.65, 0.65};
1094  static float skew[2] = {0, 0};
1095  static float path_rect[4] = {0, 0,
1096  static_cast<float>(boston->GetSize().width),
1097  static_cast<float>(boston->GetSize().height)};
1098  static float effect_transform_scale = 1;
1099 
1100  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
1101  {
1102  ImGui::Combo("Morphology type", &selected_morphology_type,
1103  morphology_type_names,
1104  sizeof(morphology_type_names) / sizeof(char*));
1105  ImGui::SliderFloat2("Radius", radius, 0, 200);
1106  ImGui::SliderFloat("Input opacity", &input_color.alpha, 0, 1);
1107  ImGui::ColorEdit4("Cover color", reinterpret_cast<float*>(&cover_color));
1108  ImGui::ColorEdit4("Bounds color ",
1109  reinterpret_cast<float*>(&bounds_color));
1110  ImGui::SliderFloat2("Translation", offset, 0,
1111  pass.GetRenderTargetSize().width);
1112  ImGui::SliderFloat("Rotation", &rotation, 0, kPi * 2);
1113  ImGui::SliderFloat2("Scale", scale, 0, 3);
1114  ImGui::SliderFloat2("Skew", skew, -3, 3);
1115  ImGui::SliderFloat4("Path XYWH", path_rect, -1000, 1000);
1116  ImGui::SliderFloat("Effect transform scale", &effect_transform_scale, 0,
1117  3);
1118  }
1119  ImGui::End();
1120 
1121  std::shared_ptr<Contents> input;
1122  Size input_size;
1123 
1124  auto input_rect =
1125  Rect::MakeXYWH(path_rect[0], path_rect[1], path_rect[2], path_rect[3]);
1126  auto texture = std::make_shared<TextureContents>();
1127  texture->SetSourceRect(Rect::MakeSize(boston->GetSize()));
1128  texture->SetDestinationRect(input_rect);
1129  texture->SetTexture(boston);
1130  texture->SetOpacity(input_color.alpha);
1131 
1132  input = texture;
1133  input_size = input_rect.GetSize();
1134 
1135  auto contents = FilterContents::MakeMorphology(
1136  FilterInput::Make(input), Radius{radius[0]}, Radius{radius[1]},
1137  morphology_types[selected_morphology_type]);
1138  contents->SetEffectTransform(Matrix::MakeScale(
1139  Vector2{effect_transform_scale, effect_transform_scale}));
1140 
1141  auto ctm = Matrix::MakeScale(GetContentScale()) *
1142  Matrix::MakeTranslation(Vector3(offset[0], offset[1])) *
1143  Matrix::MakeRotationZ(Radians(rotation)) *
1144  Matrix::MakeScale(Vector2(scale[0], scale[1])) *
1145  Matrix::MakeSkew(skew[0], skew[1]) *
1146  Matrix::MakeTranslation(-Point(input_size) / 2);
1147 
1148  Entity entity;
1149  entity.SetContents(contents);
1150  entity.SetTransform(ctm);
1151 
1152  entity.Render(context, pass);
1153 
1154  // Renders a red "cover" rectangle that shows the original position of the
1155  // unfiltered input.
1156  Entity cover_entity;
1157  std::unique_ptr<Geometry> geom =
1158  Geometry::MakeFillPath(PathBuilder{}.AddRect(input_rect).TakePath());
1159  auto cover_contents = std::make_shared<SolidColorContents>();
1160  cover_contents->SetColor(cover_color);
1161  cover_contents->SetGeometry(geom.get());
1162  cover_entity.SetContents(cover_contents);
1163  cover_entity.SetTransform(ctm);
1164  cover_entity.Render(context, pass);
1165 
1166  // Renders a green bounding rect of the target filter.
1167  Entity bounds_entity;
1168  std::unique_ptr<Geometry> bounds_geom = Geometry::MakeFillPath(
1169  PathBuilder{}
1170  .AddRect(contents->GetCoverage(entity).value())
1171  .TakePath());
1172  auto bounds_contents = std::make_shared<SolidColorContents>();
1173  bounds_contents->SetColor(bounds_color);
1174  bounds_contents->SetGeometry(bounds_geom.get());
1175  bounds_entity.SetContents(std::move(bounds_contents));
1176  bounds_entity.SetTransform(Matrix());
1177 
1178  bounds_entity.Render(context, pass);
1179 
1180  return true;
1181  };
1182  ASSERT_TRUE(OpenPlaygroundHere(callback));
1183 }

References impeller::PathBuilder::AddRect(), impeller::Color::alpha, impeller::Color::Black(), impeller::FilterContents::kDilate, impeller::FilterContents::kErode, impeller::kPi, impeller::FilterInput::Make(), impeller::Geometry::MakeFillPath(), impeller::FilterContents::MakeMorphology(), impeller::Matrix::MakeRotationZ(), impeller::Matrix::MakeScale(), impeller::TRect< Scalar >::MakeSize(), impeller::Matrix::MakeSkew(), impeller::Matrix::MakeTranslation(), impeller::TRect< Scalar >::MakeXYWH(), offset, impeller::Entity::Render(), scale, impeller::Entity::SetContents(), impeller::Entity::SetTransform(), and impeller::PathBuilder::TakePath().

◆ TEST_P() [383/497]

impeller::testing::TEST_P ( EntityTest  ,
PointFieldGeometryCoverage   
)

Definition at line 2080 of file entity_unittests.cc.

2080  {
2081  std::vector<Point> points = {{10, 20}, {100, 200}};
2082  PointFieldGeometry geometry(points.data(), 2, 5.0, false);
2083  ASSERT_EQ(geometry.GetCoverage(Matrix()), Rect::MakeLTRB(5, 15, 105, 205));
2084  ASSERT_EQ(geometry.GetCoverage(Matrix::MakeTranslation({30, 0, 0})),
2085  Rect::MakeLTRB(35, 15, 135, 205));
2086 }

References impeller::PointFieldGeometry::GetCoverage(), impeller::TRect< Scalar >::MakeLTRB(), and impeller::Matrix::MakeTranslation().

◆ TEST_P() [384/497]

impeller::testing::TEST_P ( EntityTest  ,
RadialGradientContentsIsOpaque   
)

Definition at line 2021 of file entity_unittests.cc.

2021  {
2022  Matrix matrix;
2023  RadialGradientContents contents;
2024  auto geom = Geometry::MakeRect(Rect::MakeLTRB(0, 0, 10, 10));
2025  contents.SetGeometry(geom.get());
2026 
2027  contents.SetColors({Color::CornflowerBlue()});
2028  EXPECT_TRUE(contents.IsOpaque(matrix));
2029  contents.SetColors({Color::CornflowerBlue().WithAlpha(0.5)});
2030  EXPECT_FALSE(contents.IsOpaque(matrix));
2031  contents.SetColors({Color::CornflowerBlue()});
2032  contents.SetTileMode(Entity::TileMode::kDecal);
2033  EXPECT_FALSE(contents.IsOpaque(matrix));
2034 
2035  // Create stroked path that required alpha coverage.
2036  geom = Geometry::MakeStrokePath(
2037  PathBuilder{}.AddLine({0, 0}, {100, 100}).TakePath(),
2038  /*stroke_width=*/0.05);
2039  contents.SetGeometry(geom.get());
2040  contents.SetColors({Color::CornflowerBlue()});
2041 
2042  EXPECT_FALSE(contents.IsOpaque(matrix));
2043 }

References impeller::PathBuilder::AddLine(), impeller::Color::CornflowerBlue(), impeller::RadialGradientContents::IsOpaque(), impeller::Entity::kDecal, impeller::TRect< Scalar >::MakeLTRB(), impeller::Geometry::MakeRect(), impeller::Geometry::MakeStrokePath(), impeller::RadialGradientContents::SetColors(), impeller::ColorSourceContents::SetGeometry(), impeller::RadialGradientContents::SetTileMode(), and impeller::Color::WithAlpha().

◆ TEST_P() [385/497]

impeller::testing::TEST_P ( EntityTest  ,
RRectShadowTest   
)

Definition at line 1328 of file entity_unittests.cc.

1328  {
1329  auto callback = [&](ContentContext& context, RenderPass& pass) {
1330  static Color color = Color::Red();
1331  static float corner_radius = 100;
1332  static float blur_radius = 100;
1333  static bool show_coverage = false;
1334  static Color coverage_color = Color::Green().WithAlpha(0.2);
1335 
1336  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
1337  ImGui::SliderFloat("Corner radius", &corner_radius, 0, 300);
1338  ImGui::SliderFloat("Blur radius", &blur_radius, 0, 300);
1339  ImGui::ColorEdit4("Color", reinterpret_cast<Scalar*>(&color));
1340  ImGui::Checkbox("Show coverage", &show_coverage);
1341  if (show_coverage) {
1342  ImGui::ColorEdit4("Coverage color",
1343  reinterpret_cast<Scalar*>(&coverage_color));
1344  }
1345  ImGui::End();
1346 
1347  PlaygroundPoint top_left_point(Point(200, 200), 30, Color::White());
1348  PlaygroundPoint bottom_right_point(Point(600, 400), 30, Color::White());
1349  auto [top_left, bottom_right] =
1350  DrawPlaygroundLine(top_left_point, bottom_right_point);
1351  auto rect =
1352  Rect::MakeLTRB(top_left.x, top_left.y, bottom_right.x, bottom_right.y);
1353 
1354  auto contents = std::make_unique<SolidRRectBlurContents>();
1355  contents->SetRRect(rect, {corner_radius, corner_radius});
1356  contents->SetColor(color);
1357  contents->SetSigma(Radius(blur_radius));
1358 
1359  Entity entity;
1360  entity.SetTransform(Matrix::MakeScale(GetContentScale()));
1361  entity.SetContents(std::move(contents));
1362  entity.Render(context, pass);
1363 
1364  auto coverage = entity.GetCoverage();
1365  if (show_coverage && coverage.has_value()) {
1366  auto bounds_contents = std::make_unique<SolidColorContents>();
1367  auto geom = Geometry::MakeFillPath(
1368  PathBuilder{}.AddRect(entity.GetCoverage().value()).TakePath());
1369  bounds_contents->SetGeometry(geom.get());
1370  bounds_contents->SetColor(coverage_color.Premultiply());
1371  Entity bounds_entity;
1372  bounds_entity.SetContents(std::move(bounds_contents));
1373  bounds_entity.Render(context, pass);
1374  }
1375 
1376  return true;
1377  };
1378  ASSERT_TRUE(OpenPlaygroundHere(callback));
1379 }

References impeller::PathBuilder::AddRect(), blur_radius, impeller::DrawPlaygroundLine(), impeller::Entity::GetCoverage(), impeller::Color::Green(), impeller::Geometry::MakeFillPath(), impeller::TRect< Scalar >::MakeLTRB(), impeller::Matrix::MakeScale(), impeller::Color::Premultiply(), impeller::Color::Red(), impeller::Entity::Render(), impeller::Entity::SetContents(), impeller::Entity::SetTransform(), impeller::PathBuilder::TakePath(), impeller::Color::White(), and impeller::Color::WithAlpha().

◆ TEST_P() [386/497]

impeller::testing::TEST_P ( EntityTest  ,
RuntimeEffect   
)

Definition at line 1687 of file entity_unittests.cc.

1687  {
1688  auto runtime_stages =
1689  OpenAssetAsRuntimeStage("runtime_stage_example.frag.iplr");
1690  auto runtime_stage =
1691  runtime_stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
1692  ASSERT_TRUE(runtime_stage);
1693  ASSERT_TRUE(runtime_stage->IsDirty());
1694 
1695  bool expect_dirty = true;
1696 
1697  PipelineRef first_pipeline;
1698  std::unique_ptr<Geometry> geom = Geometry::MakeCover();
1699 
1700  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
1701  EXPECT_EQ(runtime_stage->IsDirty(), expect_dirty);
1702 
1703  auto contents = std::make_shared<RuntimeEffectContents>();
1704  contents->SetGeometry(geom.get());
1705  contents->SetRuntimeStage(runtime_stage);
1706 
1707  struct FragUniforms {
1708  Vector2 iResolution;
1709  Scalar iTime;
1710  } frag_uniforms = {
1711  .iResolution = Vector2(GetWindowSize().width, GetWindowSize().height),
1712  .iTime = static_cast<Scalar>(GetSecondsElapsed()),
1713  };
1714  auto uniform_data = std::make_shared<std::vector<uint8_t>>();
1715  uniform_data->resize(sizeof(FragUniforms));
1716  memcpy(uniform_data->data(), &frag_uniforms, sizeof(FragUniforms));
1717  contents->SetUniformData(uniform_data);
1718 
1719  Entity entity;
1720  entity.SetContents(contents);
1721  bool result = contents->Render(context, entity, pass);
1722 
1723  if (expect_dirty) {
1724  first_pipeline = pass.GetCommands().back().pipeline;
1725  } else {
1726  EXPECT_EQ(pass.GetCommands().back().pipeline, first_pipeline);
1727  }
1728  expect_dirty = false;
1729  return result;
1730  };
1731 
1732  // Simulate some renders and hot reloading of the shader.
1733  auto content_context = GetContentContext();
1734  {
1735  RenderTarget target =
1736  content_context->GetRenderTargetCache()->CreateOffscreen(
1737  *content_context->GetContext(), {1, 1}, 1u);
1738 
1739  testing::MockRenderPass mock_pass(GetContext(), target);
1740  callback(*content_context, mock_pass);
1741  callback(*content_context, mock_pass);
1742 
1743  // Dirty the runtime stage.
1744  runtime_stages = OpenAssetAsRuntimeStage("runtime_stage_example.frag.iplr");
1745  runtime_stage =
1746  runtime_stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
1747 
1748  ASSERT_TRUE(runtime_stage->IsDirty());
1749  expect_dirty = true;
1750 
1751  callback(*content_context, mock_pass);
1752  }
1753 }
raw_ptr< Pipeline< PipelineDescriptor > > PipelineRef
A raw ptr to a pipeline object.
Definition: pipeline.h:86

References impeller::Geometry::MakeCover(), impeller::PlaygroundBackendToRuntimeStageBackend(), and impeller::Entity::SetContents().

◆ TEST_P() [387/497]

impeller::testing::TEST_P ( EntityTest  ,
RuntimeEffectCanPrecache   
)

Definition at line 1802 of file entity_unittests.cc.

1802  {
1803  auto runtime_stages =
1804  OpenAssetAsRuntimeStage("runtime_stage_example.frag.iplr");
1805  auto runtime_stage =
1806  runtime_stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
1807  ASSERT_TRUE(runtime_stage);
1808  ASSERT_TRUE(runtime_stage->IsDirty());
1809 
1810  auto contents = std::make_shared<RuntimeEffectContents>();
1811  contents->SetRuntimeStage(runtime_stage);
1812 
1813  EXPECT_TRUE(contents->BootstrapShader(*GetContentContext()));
1814 }

References impeller::PlaygroundBackendToRuntimeStageBackend().

◆ TEST_P() [388/497]

impeller::testing::TEST_P ( EntityTest  ,
RuntimeEffectCanSuccessfullyRender   
)

Definition at line 1755 of file entity_unittests.cc.

1755  {
1756  auto runtime_stages =
1757  OpenAssetAsRuntimeStage("runtime_stage_example.frag.iplr");
1758  auto runtime_stage =
1759  runtime_stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
1760  ASSERT_TRUE(runtime_stage);
1761  ASSERT_TRUE(runtime_stage->IsDirty());
1762 
1763  auto contents = std::make_shared<RuntimeEffectContents>();
1764  auto geom = Geometry::MakeCover();
1765  contents->SetGeometry(geom.get());
1766  contents->SetRuntimeStage(runtime_stage);
1767 
1768  struct FragUniforms {
1769  Vector2 iResolution;
1770  Scalar iTime;
1771  } frag_uniforms = {
1772  .iResolution = Vector2(GetWindowSize().width, GetWindowSize().height),
1773  .iTime = static_cast<Scalar>(GetSecondsElapsed()),
1774  };
1775  auto uniform_data = std::make_shared<std::vector<uint8_t>>();
1776  uniform_data->resize(sizeof(FragUniforms));
1777  memcpy(uniform_data->data(), &frag_uniforms, sizeof(FragUniforms));
1778  contents->SetUniformData(uniform_data);
1779 
1780  Entity entity;
1781  entity.SetContents(contents);
1782 
1783  // Create a render target with a depth-stencil, similar to how EntityPass
1784  // does.
1785  RenderTarget target =
1786  GetContentContext()->GetRenderTargetCache()->CreateOffscreenMSAA(
1787  *GetContext(), {GetWindowSize().width, GetWindowSize().height}, 1,
1788  "RuntimeEffect Texture");
1789  testing::MockRenderPass pass(GetContext(), target);
1790 
1791  ASSERT_TRUE(contents->Render(*GetContentContext(), entity, pass));
1792  ASSERT_EQ(pass.GetCommands().size(), 1u);
1793  const auto& command = pass.GetCommands()[0];
1794  ASSERT_TRUE(command.pipeline->GetDescriptor()
1795  .GetDepthStencilAttachmentDescriptor()
1796  .has_value());
1797  ASSERT_TRUE(command.pipeline->GetDescriptor()
1798  .GetFrontStencilAttachmentDescriptor()
1799  .has_value());
1800 }

References impeller::Geometry::MakeCover(), impeller::PlaygroundBackendToRuntimeStageBackend(), and impeller::Entity::SetContents().

◆ TEST_P() [389/497]

impeller::testing::TEST_P ( EntityTest  ,
RuntimeEffectSetsRightSizeWhenUniformIsStruct   
)

Definition at line 1816 of file entity_unittests.cc.

1816  {
1817  if (GetBackend() != PlaygroundBackend::kVulkan) {
1818  GTEST_SKIP() << "Test only applies to Vulkan";
1819  }
1820 
1821  auto runtime_stages =
1822  OpenAssetAsRuntimeStage("runtime_stage_example.frag.iplr");
1823  auto runtime_stage =
1824  runtime_stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
1825  ASSERT_TRUE(runtime_stage);
1826  ASSERT_TRUE(runtime_stage->IsDirty());
1827 
1828  auto contents = std::make_shared<RuntimeEffectContents>();
1829  auto geom = Geometry::MakeCover();
1830  contents->SetGeometry(geom.get());
1831  contents->SetRuntimeStage(runtime_stage);
1832 
1833  struct FragUniforms {
1834  Vector2 iResolution;
1835  Scalar iTime;
1836  } frag_uniforms = {
1837  .iResolution = Vector2(GetWindowSize().width, GetWindowSize().height),
1838  .iTime = static_cast<Scalar>(GetSecondsElapsed()),
1839  };
1840  auto uniform_data = std::make_shared<std::vector<uint8_t>>();
1841  uniform_data->resize(sizeof(FragUniforms));
1842  memcpy(uniform_data->data(), &frag_uniforms, sizeof(FragUniforms));
1843 
1844  auto buffer_view = RuntimeEffectContents::EmplaceVulkanUniform(
1845  uniform_data, GetContentContext()->GetTransientsBuffer(),
1846  runtime_stage->GetUniforms()[0]);
1847 
1848  // 16 bytes:
1849  // 8 bytes for iResolution
1850  // 4 bytes for iTime
1851  // 4 bytes padding
1852  EXPECT_EQ(buffer_view.GetRange().length, 16u);
1853 }

References buffer_view, impeller::RuntimeEffectContents::EmplaceVulkanUniform(), impeller::kVulkan, impeller::Geometry::MakeCover(), and impeller::PlaygroundBackendToRuntimeStageBackend().

◆ TEST_P() [390/497]

impeller::testing::TEST_P ( EntityTest  ,
SetBlendMode   
)

Definition at line 1185 of file entity_unittests.cc.

1185  {
1186  Entity entity;
1187  ASSERT_EQ(entity.GetBlendMode(), BlendMode::kSourceOver);
1188  entity.SetBlendMode(BlendMode::kClear);
1189  ASSERT_EQ(entity.GetBlendMode(), BlendMode::kClear);
1190 }

References impeller::Entity::GetBlendMode(), impeller::kClear, impeller::kSourceOver, and impeller::Entity::SetBlendMode().

◆ TEST_P() [391/497]

impeller::testing::TEST_P ( EntityTest  ,
SolidColorApplyColorFilter   
)

Definition at line 2418 of file entity_unittests.cc.

2418  {
2419  auto contents = SolidColorContents();
2420  contents.SetColor(Color::CornflowerBlue().WithAlpha(0.75));
2421  auto result = contents.ApplyColorFilter([](const Color& color) {
2422  return color.Blend(Color::LimeGreen().WithAlpha(0.75), BlendMode::kScreen);
2423  });
2424  ASSERT_TRUE(result);
2425  ASSERT_COLOR_NEAR(contents.GetColor(),
2426  Color(0.424452, 0.828743, 0.79105, 0.9375));
2427 }

References ASSERT_COLOR_NEAR, impeller::Color::Blend(), impeller::Color::CornflowerBlue(), impeller::kScreen, and impeller::Color::LimeGreen().

◆ TEST_P() [392/497]

impeller::testing::TEST_P ( EntityTest  ,
SolidColorContentsIsOpaque   
)

Definition at line 1955 of file entity_unittests.cc.

1955  {
1956  Matrix matrix;
1957  SolidColorContents contents;
1958  auto geom = Geometry::MakeRect(Rect::MakeLTRB(0, 0, 10, 10));
1959  contents.SetGeometry(geom.get());
1960 
1961  contents.SetColor(Color::CornflowerBlue());
1962  EXPECT_TRUE(contents.IsOpaque(matrix));
1963  contents.SetColor(Color::CornflowerBlue().WithAlpha(0.5));
1964  EXPECT_FALSE(contents.IsOpaque(matrix));
1965 
1966  // Create stroked path that required alpha coverage.
1967  geom = Geometry::MakeStrokePath(
1968  PathBuilder{}.AddLine({0, 0}, {100, 100}).TakePath(),
1969  /*stroke_width=*/0.05);
1970  contents.SetGeometry(geom.get());
1971  contents.SetColor(Color::CornflowerBlue());
1972 
1973  EXPECT_FALSE(contents.IsOpaque(matrix));
1974 }

References impeller::PathBuilder::AddLine(), impeller::Color::CornflowerBlue(), impeller::SolidColorContents::IsOpaque(), impeller::TRect< Scalar >::MakeLTRB(), impeller::Geometry::MakeRect(), impeller::Geometry::MakeStrokePath(), impeller::SolidColorContents::SetColor(), and impeller::ColorSourceContents::SetGeometry().

◆ TEST_P() [393/497]

impeller::testing::TEST_P ( EntityTest  ,
SolidColorContentsStrokeSetMiterLimit   
)

Definition at line 672 of file entity_unittests.cc.

672  {
673  {
674  auto geometry = Geometry::MakeStrokePath(Path{});
675  auto path_geometry = static_cast<StrokePathGeometry*>(geometry.get());
676  ASSERT_FLOAT_EQ(path_geometry->GetMiterLimit(), 4);
677  }
678 
679  {
680  auto geometry = Geometry::MakeStrokePath(Path{}, 1.0,
681  /*miter_limit=*/8.0);
682  auto path_geometry = static_cast<StrokePathGeometry*>(geometry.get());
683  ASSERT_FLOAT_EQ(path_geometry->GetMiterLimit(), 8);
684  }
685 
686  {
687  auto geometry = Geometry::MakeStrokePath(Path{}, 1.0,
688  /*miter_limit=*/-1.0);
689  auto path_geometry = static_cast<StrokePathGeometry*>(geometry.get());
690  ASSERT_FLOAT_EQ(path_geometry->GetMiterLimit(), 4);
691  }
692 }

References impeller::Geometry::MakeStrokePath().

◆ TEST_P() [394/497]

impeller::testing::TEST_P ( EntityTest  ,
SolidColorContentsStrokeSetStrokeCapsAndJoins   
)

Definition at line 650 of file entity_unittests.cc.

650  {
651  {
652  auto geometry = Geometry::MakeStrokePath(Path{});
653  auto path_geometry = static_cast<StrokePathGeometry*>(geometry.get());
654  // Defaults.
655  ASSERT_EQ(path_geometry->GetStrokeCap(), Cap::kButt);
656  ASSERT_EQ(path_geometry->GetStrokeJoin(), Join::kMiter);
657  }
658 
659  {
660  auto geometry = Geometry::MakeStrokePath(Path{}, 1.0, 4.0, Cap::kSquare);
661  auto path_geometry = static_cast<StrokePathGeometry*>(geometry.get());
662  ASSERT_EQ(path_geometry->GetStrokeCap(), Cap::kSquare);
663  }
664 
665  {
666  auto geometry = Geometry::MakeStrokePath(Path{}, 1.0, 4.0, Cap::kRound);
667  auto path_geometry = static_cast<StrokePathGeometry*>(geometry.get());
668  ASSERT_EQ(path_geometry->GetStrokeCap(), Cap::kRound);
669  }
670 }

References impeller::kButt, impeller::kMiter, impeller::kRound, impeller::kSquare, and impeller::Geometry::MakeStrokePath().

◆ TEST_P() [395/497]

impeller::testing::TEST_P ( EntityTest  ,
SolidFillCoverageIsCorrect   
)

Definition at line 1282 of file entity_unittests.cc.

1282  {
1283  // No transform
1284  {
1285  auto fill = std::make_shared<SolidColorContents>();
1286  fill->SetColor(Color::CornflowerBlue());
1287  auto expected = Rect::MakeLTRB(100, 110, 200, 220);
1288  auto geom =
1289  Geometry::MakeFillPath(PathBuilder{}.AddRect(expected).TakePath());
1290  fill->SetGeometry(geom.get());
1291 
1292  auto coverage = fill->GetCoverage({});
1293  ASSERT_TRUE(coverage.has_value());
1294  ASSERT_RECT_NEAR(coverage.value(), expected);
1295  }
1296 
1297  // Entity transform
1298  {
1299  auto fill = std::make_shared<SolidColorContents>();
1300  auto geom = Geometry::MakeFillPath(
1301  PathBuilder{}.AddRect(Rect::MakeLTRB(100, 110, 200, 220)).TakePath());
1302  fill->SetColor(Color::CornflowerBlue());
1303  fill->SetGeometry(geom.get());
1304 
1305  Entity entity;
1306  entity.SetTransform(Matrix::MakeTranslation(Vector2(4, 5)));
1307  entity.SetContents(std::move(fill));
1308 
1309  auto coverage = entity.GetCoverage();
1310  auto expected = Rect::MakeLTRB(104, 115, 204, 225);
1311  ASSERT_TRUE(coverage.has_value());
1312  ASSERT_RECT_NEAR(coverage.value(), expected);
1313  }
1314 
1315  // No coverage for fully transparent colors
1316  {
1317  auto fill = std::make_shared<SolidColorContents>();
1318  auto geom = Geometry::MakeFillPath(
1319  PathBuilder{}.AddRect(Rect::MakeLTRB(100, 110, 200, 220)).TakePath());
1320  fill->SetColor(Color::WhiteTransparent());
1321  fill->SetGeometry(geom.get());
1322 
1323  auto coverage = fill->GetCoverage({});
1324  ASSERT_FALSE(coverage.has_value());
1325  }
1326 }

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() [396/497]

impeller::testing::TEST_P ( EntityTest  ,
SolidStrokeCoverageIsCorrect   
)

Definition at line 1198 of file entity_unittests.cc.

1198  {
1199  {
1200  auto geometry = Geometry::MakeStrokePath(
1201  PathBuilder{}.AddLine({0, 0}, {10, 10}).TakePath(), 4.0, 4.0,
1202  Cap::kButt, Join::kBevel);
1203 
1204  Entity entity;
1205  auto contents = std::make_unique<SolidColorContents>();
1206  contents->SetGeometry(geometry.get());
1207  contents->SetColor(Color::Black());
1208  entity.SetContents(std::move(contents));
1209  auto actual = entity.GetCoverage();
1210  auto expected = Rect::MakeLTRB(-2, -2, 12, 12);
1211 
1212  ASSERT_TRUE(actual.has_value());
1213  ASSERT_RECT_NEAR(actual.value(), expected);
1214  }
1215 
1216  // Cover the Cap::kSquare case.
1217  {
1218  auto geometry = Geometry::MakeStrokePath(
1219  PathBuilder{}.AddLine({0, 0}, {10, 10}).TakePath(), 4.0, 4.0,
1220  Cap::kSquare, Join::kBevel);
1221 
1222  Entity entity;
1223  auto contents = std::make_unique<SolidColorContents>();
1224  contents->SetGeometry(geometry.get());
1225  contents->SetColor(Color::Black());
1226  entity.SetContents(std::move(contents));
1227  auto actual = entity.GetCoverage();
1228  auto expected =
1229  Rect::MakeLTRB(-sqrt(8), -sqrt(8), 10 + sqrt(8), 10 + sqrt(8));
1230 
1231  ASSERT_TRUE(actual.has_value());
1232  ASSERT_RECT_NEAR(actual.value(), expected);
1233  }
1234 
1235  // Cover the Join::kMiter case.
1236  {
1237  auto geometry = Geometry::MakeStrokePath(
1238  PathBuilder{}.AddLine({0, 0}, {10, 10}).TakePath(), 4.0, 2.0,
1239  Cap::kSquare, Join::kMiter);
1240 
1241  Entity entity;
1242  auto contents = std::make_unique<SolidColorContents>();
1243  contents->SetGeometry(geometry.get());
1244  contents->SetColor(Color::Black());
1245  entity.SetContents(std::move(contents));
1246  auto actual = entity.GetCoverage();
1247  auto expected = Rect::MakeLTRB(-4, -4, 14, 14);
1248 
1249  ASSERT_TRUE(actual.has_value());
1250  ASSERT_RECT_NEAR(actual.value(), expected);
1251  }
1252 }

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() [397/497]

impeller::testing::TEST_P ( EntityTest  ,
SpecializationConstantsAreAppliedToVariants   
)

Definition at line 2116 of file entity_unittests.cc.

2116  {
2117  auto content_context = GetContentContext();
2118 
2119  auto default_gyph = content_context->GetGlyphAtlasPipeline({
2120  .color_attachment_pixel_format = PixelFormat::kR8G8B8A8UNormInt,
2121  .has_depth_stencil_attachments = false,
2122  });
2123  auto alt_gyph = content_context->GetGlyphAtlasPipeline(
2124  {.color_attachment_pixel_format = PixelFormat::kR8G8B8A8UNormInt,
2125  .has_depth_stencil_attachments = true});
2126 
2127  EXPECT_NE(default_gyph, alt_gyph);
2128  EXPECT_EQ(default_gyph->GetDescriptor().GetSpecializationConstants(),
2129  alt_gyph->GetDescriptor().GetSpecializationConstants());
2130 
2131  auto use_a8 = GetContext()->GetCapabilities()->GetDefaultGlyphAtlasFormat() ==
2132  PixelFormat::kA8UNormInt;
2133 
2134  std::vector<Scalar> expected_constants = {static_cast<Scalar>(use_a8)};
2135  EXPECT_EQ(default_gyph->GetDescriptor().GetSpecializationConstants(),
2136  expected_constants);
2137 }

References impeller::kA8UNormInt, and impeller::kR8G8B8A8UNormInt.

◆ TEST_P() [398/497]

impeller::testing::TEST_P ( EntityTest  ,
SrgbToLinearFilter   
)

Definition at line 1544 of file entity_unittests.cc.

1544  {
1545  auto image = CreateTextureForFixture("embarcadero.jpg");
1546  ASSERT_TRUE(image);
1547 
1548  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
1549  auto filtered =
1550  ColorFilterContents::MakeSrgbToLinearFilter(FilterInput::Make(image));
1551 
1552  // Define the entity that will serve as the control image as a Gaussian blur
1553  // filter with no filter at all.
1554  Entity entity_left;
1555  entity_left.SetTransform(Matrix::MakeScale(GetContentScale()) *
1556  Matrix::MakeTranslation({100, 300}) *
1557  Matrix::MakeScale(Vector2{0.5, 0.5}));
1558  auto unfiltered = FilterContents::MakeGaussianBlur(FilterInput::Make(image),
1559  Sigma{0}, Sigma{0});
1560  entity_left.SetContents(unfiltered);
1561 
1562  // Define the entity that will be filtered from sRGB to linear.
1563  Entity entity_right;
1564  entity_right.SetTransform(Matrix::MakeScale(GetContentScale()) *
1565  Matrix::MakeTranslation({500, 300}) *
1566  Matrix::MakeScale(Vector2{0.5, 0.5}));
1567  entity_right.SetContents(filtered);
1568  return entity_left.Render(context, pass) &&
1569  entity_right.Render(context, pass);
1570  };
1571 
1572  ASSERT_TRUE(OpenPlaygroundHere(callback));
1573 }

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() [399/497]

impeller::testing::TEST_P ( EntityTest  ,
SrgbToLinearFilterCoverageIsCorrect   
)

Definition at line 1522 of file entity_unittests.cc.

1522  {
1523  // Set up a simple color background.
1524  auto fill = std::make_shared<SolidColorContents>();
1525  auto geom = Geometry::MakeFillPath(
1526  PathBuilder{}.AddRect(Rect::MakeXYWH(0, 0, 300, 400)).TakePath());
1527  fill->SetGeometry(geom.get());
1528  fill->SetColor(Color::DeepPink());
1529 
1530  auto filter =
1531  ColorFilterContents::MakeSrgbToLinearFilter(FilterInput::Make(fill));
1532 
1533  Entity e;
1534  e.SetTransform(Matrix());
1535 
1536  // Confirm that the actual filter coverage matches the expected coverage.
1537  auto actual = filter->GetCoverage(e);
1538  auto expected = Rect::MakeXYWH(0, 0, 300, 400);
1539 
1540  ASSERT_TRUE(actual.has_value());
1541  ASSERT_RECT_NEAR(actual.value(), expected);
1542 }

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() [400/497]

impeller::testing::TEST_P ( EntityTest  ,
StrokeCapAndJoinTest   
)

Definition at line 192 of file entity_unittests.cc.

192  {
193  const Point padding(300, 250);
194  const Point margin(140, 180);
195 
196  auto callback = [&](ContentContext& context, RenderPass& pass) {
197  // Slightly above sqrt(2) by default, so that right angles are just below
198  // the limit and acute angles are over the limit (causing them to get
199  // beveled).
200  static Scalar miter_limit = 1.41421357;
201  static Scalar width = 30;
202 
203  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
204  {
205  ImGui::SliderFloat("Miter limit", &miter_limit, 0, 30);
206  ImGui::SliderFloat("Stroke width", &width, 0, 100);
207  if (ImGui::Button("Reset")) {
208  miter_limit = 1.41421357;
209  width = 30;
210  }
211  }
212  ImGui::End();
213 
214  auto world_matrix = Matrix::MakeScale(GetContentScale());
215  auto render_path = [width = width, &context, &pass, &world_matrix](
216  const Path& path, Cap cap, Join join) {
217  auto contents = std::make_unique<SolidColorContents>();
218  std::unique_ptr<Geometry> geom =
219  Geometry::MakeStrokePath(path, width, miter_limit, cap, join);
220  contents->SetGeometry(geom.get());
221  contents->SetColor(Color::Red());
222 
223  Entity entity;
224  entity.SetTransform(world_matrix);
225  entity.SetContents(std::move(contents));
226 
227  auto coverage = entity.GetCoverage();
228  if (coverage.has_value()) {
229  auto bounds_contents = std::make_unique<SolidColorContents>();
230 
231  std::unique_ptr<Geometry> geom = Geometry::MakeFillPath(
232  PathBuilder{}.AddRect(entity.GetCoverage().value()).TakePath());
233 
234  bounds_contents->SetGeometry(geom.get());
235  bounds_contents->SetColor(Color::Green().WithAlpha(0.5));
236  Entity bounds_entity;
237  bounds_entity.SetContents(std::move(bounds_contents));
238  bounds_entity.Render(context, pass);
239  }
240 
241  entity.Render(context, pass);
242  };
243 
244  const Point a_def(0, 0), b_def(0, 100), c_def(150, 0), d_def(150, -100),
245  e_def(75, 75);
246  const Scalar r = 30;
247  // Cap::kButt demo.
248  {
249  Point off = Point(0, 0) * padding + margin;
250  PlaygroundPoint point_a(off + a_def, r, Color::Black());
251  PlaygroundPoint point_b(off + b_def, r, Color::White());
252  auto [a, b] = DrawPlaygroundLine(point_a, point_b);
253  PlaygroundPoint point_c(off + c_def, r, Color::Black());
254  PlaygroundPoint point_d(off + d_def, r, Color::White());
255  auto [c, d] = DrawPlaygroundLine(point_c, point_d);
256  render_path(PathBuilder{}.AddCubicCurve(a, b, d, c).TakePath(),
257  Cap::kButt, Join::kBevel);
258  }
259 
260  // Cap::kSquare demo.
261  {
262  Point off = Point(1, 0) * padding + margin;
263  PlaygroundPoint point_a(off + a_def, r, Color::Black());
264  PlaygroundPoint point_b(off + b_def, r, Color::White());
265  auto [a, b] = DrawPlaygroundLine(point_a, point_b);
266  PlaygroundPoint point_c(off + c_def, r, Color::Black());
267  PlaygroundPoint point_d(off + d_def, r, Color::White());
268  auto [c, d] = DrawPlaygroundLine(point_c, point_d);
269  render_path(PathBuilder{}.AddCubicCurve(a, b, d, c).TakePath(),
270  Cap::kSquare, Join::kBevel);
271  }
272 
273  // Cap::kRound demo.
274  {
275  Point off = Point(2, 0) * padding + margin;
276  PlaygroundPoint point_a(off + a_def, r, Color::Black());
277  PlaygroundPoint point_b(off + b_def, r, Color::White());
278  auto [a, b] = DrawPlaygroundLine(point_a, point_b);
279  PlaygroundPoint point_c(off + c_def, r, Color::Black());
280  PlaygroundPoint point_d(off + d_def, r, Color::White());
281  auto [c, d] = DrawPlaygroundLine(point_c, point_d);
282  render_path(PathBuilder{}.AddCubicCurve(a, b, d, c).TakePath(),
283  Cap::kRound, Join::kBevel);
284  }
285 
286  // Join::kBevel demo.
287  {
288  Point off = Point(0, 1) * padding + margin;
289  PlaygroundPoint point_a = PlaygroundPoint(off + a_def, r, Color::White());
290  PlaygroundPoint point_b = PlaygroundPoint(off + e_def, r, Color::White());
291  PlaygroundPoint point_c = PlaygroundPoint(off + c_def, r, Color::White());
292  Point a = DrawPlaygroundPoint(point_a);
293  Point b = DrawPlaygroundPoint(point_b);
294  Point c = DrawPlaygroundPoint(point_c);
295  render_path(
296  PathBuilder{}.MoveTo(a).LineTo(b).LineTo(c).Close().TakePath(),
297  Cap::kButt, Join::kBevel);
298  }
299 
300  // Join::kMiter demo.
301  {
302  Point off = Point(1, 1) * padding + margin;
303  PlaygroundPoint point_a(off + a_def, r, Color::White());
304  PlaygroundPoint point_b(off + e_def, r, Color::White());
305  PlaygroundPoint point_c(off + c_def, r, Color::White());
306  Point a = DrawPlaygroundPoint(point_a);
307  Point b = DrawPlaygroundPoint(point_b);
308  Point c = DrawPlaygroundPoint(point_c);
309  render_path(
310  PathBuilder{}.MoveTo(a).LineTo(b).LineTo(c).Close().TakePath(),
311  Cap::kButt, Join::kMiter);
312  }
313 
314  // Join::kRound demo.
315  {
316  Point off = Point(2, 1) * padding + margin;
317  PlaygroundPoint point_a(off + a_def, r, Color::White());
318  PlaygroundPoint point_b(off + e_def, r, Color::White());
319  PlaygroundPoint point_c(off + c_def, r, Color::White());
320  Point a = DrawPlaygroundPoint(point_a);
321  Point b = DrawPlaygroundPoint(point_b);
322  Point c = DrawPlaygroundPoint(point_c);
323  render_path(
324  PathBuilder{}.MoveTo(a).LineTo(b).LineTo(c).Close().TakePath(),
325  Cap::kButt, Join::kRound);
326  }
327 
328  return true;
329  };
330  ASSERT_TRUE(OpenPlaygroundHere(callback));
331 }
Vector2 padding
The halo padding in source space.
Join
Definition: path.h:25
Cap
Definition: path.h:19

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() [401/497]

impeller::testing::TEST_P ( EntityTest  ,
StrokeWithTextureContents   
)

Definition at line 127 of file entity_unittests.cc.

127  {
128  auto bridge = CreateTextureForFixture("bay_bridge.jpg");
129  Path path = PathBuilder{}
130  .MoveTo({100, 100})
131  .LineTo({100, 200})
132  .MoveTo({100, 300})
133  .LineTo({100, 400})
134  .MoveTo({100, 500})
135  .LineTo({100, 600})
136  .TakePath();
137 
138  Entity entity;
139  entity.SetTransform(Matrix::MakeScale(GetContentScale()));
140  auto contents = std::make_unique<TiledTextureContents>();
141  std::unique_ptr<Geometry> geom = Geometry::MakeStrokePath(path, 100.0);
142  contents->SetGeometry(geom.get());
143  contents->SetTexture(bridge);
144  contents->SetTileModes(Entity::TileMode::kClamp, Entity::TileMode::kClamp);
145  entity.SetContents(std::move(contents));
146  ASSERT_TRUE(OpenPlaygroundHere(std::move(entity)));
147 }

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() [402/497]

impeller::testing::TEST_P ( EntityTest  ,
SweepGradientContentsIsOpaque   
)

Definition at line 2045 of file entity_unittests.cc.

2045  {
2046  Matrix matrix;
2047  RadialGradientContents contents;
2048  auto geom = Geometry::MakeRect(Rect::MakeLTRB(0, 0, 10, 10));
2049  contents.SetGeometry(geom.get());
2050 
2051  contents.SetColors({Color::CornflowerBlue()});
2052  EXPECT_TRUE(contents.IsOpaque(matrix));
2053  contents.SetColors({Color::CornflowerBlue().WithAlpha(0.5)});
2054  EXPECT_FALSE(contents.IsOpaque(matrix));
2055  contents.SetColors({Color::CornflowerBlue()});
2056  contents.SetTileMode(Entity::TileMode::kDecal);
2057  EXPECT_FALSE(contents.IsOpaque(matrix));
2058 
2059  // Create stroked path that required alpha coverage.
2060  geom = Geometry::MakeStrokePath(
2061  PathBuilder{}.AddLine({0, 0}, {100, 100}).TakePath(),
2062  /*stroke_width=*/0.05);
2063  contents.SetGeometry(geom.get());
2064  contents.SetColors({Color::CornflowerBlue()});
2065 
2066  EXPECT_FALSE(contents.IsOpaque(matrix));
2067 }

References impeller::PathBuilder::AddLine(), impeller::Color::CornflowerBlue(), impeller::RadialGradientContents::IsOpaque(), impeller::Entity::kDecal, impeller::TRect< Scalar >::MakeLTRB(), impeller::Geometry::MakeRect(), impeller::Geometry::MakeStrokePath(), impeller::RadialGradientContents::SetColors(), impeller::ColorSourceContents::SetGeometry(), impeller::RadialGradientContents::SetTileMode(), and impeller::Color::WithAlpha().

◆ TEST_P() [403/497]

impeller::testing::TEST_P ( EntityTest  ,
TextContentsCeilsGlyphScaleToDecimal   
)

Definition at line 2108 of file entity_unittests.cc.

2108  {
2109  ASSERT_EQ(TextFrame::RoundScaledFontSize(0.4321111f), 0.43f);
2110  ASSERT_EQ(TextFrame::RoundScaledFontSize(0.5321111f), 0.53f);
2111  ASSERT_EQ(TextFrame::RoundScaledFontSize(2.1f), 2.1f);
2112  ASSERT_EQ(TextFrame::RoundScaledFontSize(0.0f), 0.0f);
2113  ASSERT_EQ(TextFrame::RoundScaledFontSize(100000000.0f), 48.0f);
2114 }

References impeller::TextFrame::RoundScaledFontSize().

◆ TEST_P() [404/497]

impeller::testing::TEST_P ( EntityTest  ,
ThreeStrokesInOnePath   
)

Definition at line 106 of file entity_unittests.cc.

106  {
107  Path path = PathBuilder{}
108  .MoveTo({100, 100})
109  .LineTo({100, 200})
110  .MoveTo({100, 300})
111  .LineTo({100, 400})
112  .MoveTo({100, 500})
113  .LineTo({100, 600})
114  .TakePath();
115 
116  Entity entity;
117  entity.SetTransform(Matrix::MakeScale(GetContentScale()));
118  auto contents = std::make_unique<SolidColorContents>();
119 
120  std::unique_ptr<Geometry> geom = Geometry::MakeStrokePath(path, 5.0);
121  contents->SetGeometry(geom.get());
122  contents->SetColor(Color::Red());
123  entity.SetContents(std::move(contents));
124  ASSERT_TRUE(OpenPlaygroundHere(std::move(entity)));
125 }

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() [405/497]

impeller::testing::TEST_P ( EntityTest  ,
TiledTextureContentsIsOpaque   
)

Definition at line 2069 of file entity_unittests.cc.

2069  {
2070  Matrix matrix;
2071  auto bay_bridge = CreateTextureForFixture("bay_bridge.jpg");
2072  TiledTextureContents contents;
2073  contents.SetTexture(bay_bridge);
2074  // This is a placeholder test. Images currently never decompress as opaque
2075  // (whether in Flutter or the playground), and so this should currently always
2076  // return false in practice.
2077  EXPECT_FALSE(contents.IsOpaque(matrix));
2078 }

References impeller::TiledTextureContents::IsOpaque(), and impeller::TiledTextureContents::SetTexture().

◆ TEST_P() [406/497]

impeller::testing::TEST_P ( EntityTest  ,
TiledTextureContentsRendersWithCorrectPipeline   
)

Definition at line 21 of file tiled_texture_contents_unittests.cc.

21  {
22  TextureDescriptor texture_desc;
23  texture_desc.size = {100, 100};
24  texture_desc.type = TextureType::kTexture2D;
25  texture_desc.format = PixelFormat::kR8G8B8A8UNormInt;
26  texture_desc.storage_mode = StorageMode::kDevicePrivate;
27  auto texture =
28  GetContext()->GetResourceAllocator()->CreateTexture(texture_desc);
29 
30  auto geom = Geometry::MakeCover();
31  TiledTextureContents contents;
32  contents.SetTexture(texture);
33  contents.SetGeometry(geom.get());
34 
35  auto content_context = GetContentContext();
36  auto buffer = content_context->GetContext()->CreateCommandBuffer();
37  auto render_target =
38  GetContentContext()->GetRenderTargetCache()->CreateOffscreenMSAA(
39  *content_context->GetContext(), {100, 100},
40  /*mip_count=*/1);
41  auto render_pass = buffer->CreateRenderPass(render_target);
42  auto recording_pass = std::make_shared<RecordingRenderPass>(
43  render_pass, GetContext(), render_target);
44 
45  ASSERT_TRUE(contents.Render(*GetContentContext(), {}, *recording_pass));
46  const std::vector<Command>& commands = recording_pass->GetCommands();
47 
48  ASSERT_EQ(commands.size(), 1u);
49 #ifdef IMPELLER_DEBUG
50  EXPECT_TRUE(commands[0].pipeline->GetDescriptor().GetLabel().find(
51  "TextureFill Pipeline") != std::string::npos);
52 #endif // IMPELLER_DEBUG
53  auto options = OptionsFromPassAndEntity(*recording_pass, {});
54  options.primitive_type = PrimitiveType::kTriangleStrip;
55  EXPECT_EQ(commands[0].pipeline,
56  GetContentContext()->GetTiledTexturePipeline(options));
57 
58  if (GetParam() == PlaygroundBackend::kMetal) {
59  recording_pass->EncodeCommands();
60  }
61 }
ContentContextOptions OptionsFromPassAndEntity(const RenderPass &pass, const Entity &entity)
Definition: contents.cc:34

References impeller::TextureDescriptor::format, impeller::kDevicePrivate, impeller::kMetal, impeller::kR8G8B8A8UNormInt, impeller::kTexture2D, impeller::kTriangleStrip, impeller::Geometry::MakeCover(), impeller::OptionsFromPassAndEntity(), impeller::ContentContextOptions::primitive_type, impeller::TiledTextureContents::Render(), impeller::ColorSourceContents::SetGeometry(), impeller::TiledTextureContents::SetTexture(), impeller::TextureDescriptor::size, impeller::TextureDescriptor::storage_mode, and impeller::TextureDescriptor::type.

◆ TEST_P() [407/497]

impeller::testing::TEST_P ( EntityTest  ,
TiledTextureContentsRendersWithCorrectPipelineExternalOES   
)

Definition at line 65 of file tiled_texture_contents_unittests.cc.

65  {
66  if (GetParam() != PlaygroundBackend::kOpenGLES) {
67  GTEST_SKIP()
68  << "External OES textures are only valid for the OpenGLES backend.";
69  }
70 
71  TextureDescriptor texture_desc;
72  texture_desc.size = {100, 100};
73  texture_desc.type = TextureType::kTextureExternalOES;
74  texture_desc.format = PixelFormat::kR8G8B8A8UNormInt;
75  texture_desc.storage_mode = StorageMode::kDevicePrivate;
76  auto texture =
77  GetContext()->GetResourceAllocator()->CreateTexture(texture_desc);
78  auto contents = TextureContents::MakeRect(Rect::MakeSize(texture->GetSize()));
79  contents->SetTexture(texture);
80  contents->SetSourceRect(Rect::MakeSize(texture->GetSize()));
81  contents->SetStrictSourceRect(false);
82 
83  auto content_context = GetContentContext();
84  auto buffer = content_context->GetContext()->CreateCommandBuffer();
85  auto render_target =
86  GetContentContext()->GetRenderTargetCache()->CreateOffscreenMSAA(
87  *content_context->GetContext(), {100, 100},
88  /*mip_count=*/1);
89  auto render_pass = buffer->CreateRenderPass(render_target);
90 
91  ASSERT_TRUE(contents->Render(*GetContentContext(), {}, *render_pass));
92  const std::vector<Command>& commands = render_pass->GetCommands();
93 
94  ASSERT_EQ(commands.size(), 1u);
95 
96  auto options = OptionsFromPassAndEntity(*render_pass, {});
97  options.primitive_type = PrimitiveType::kTriangleStrip;
98  EXPECT_EQ(commands[0].pipeline,
99  GetContentContext()->GetTiledTextureExternalPipeline(options));
100 }

References impeller::TextureDescriptor::format, impeller::kDevicePrivate, impeller::kOpenGLES, impeller::kR8G8B8A8UNormInt, impeller::kTextureExternalOES, impeller::kTriangleStrip, impeller::TextureContents::MakeRect(), impeller::TRect< Scalar >::MakeSize(), impeller::OptionsFromPassAndEntity(), impeller::ContentContextOptions::primitive_type, impeller::TextureDescriptor::size, impeller::TextureDescriptor::storage_mode, and impeller::TextureDescriptor::type.

◆ TEST_P() [408/497]

impeller::testing::TEST_P ( EntityTest  ,
TriangleInsideASquare   
)

Definition at line 149 of file entity_unittests.cc.

149  {
150  auto callback = [&](ContentContext& context, RenderPass& pass) {
151  Point offset(100, 100);
152 
153  PlaygroundPoint point_a(Point(10, 10) + offset, 20, Color::White());
154  Point a = DrawPlaygroundPoint(point_a);
155  PlaygroundPoint point_b(Point(210, 10) + offset, 20, Color::White());
156  Point b = DrawPlaygroundPoint(point_b);
157  PlaygroundPoint point_c(Point(210, 210) + offset, 20, Color::White());
158  Point c = DrawPlaygroundPoint(point_c);
159  PlaygroundPoint point_d(Point(10, 210) + offset, 20, Color::White());
160  Point d = DrawPlaygroundPoint(point_d);
161  PlaygroundPoint point_e(Point(50, 50) + offset, 20, Color::White());
162  Point e = DrawPlaygroundPoint(point_e);
163  PlaygroundPoint point_f(Point(100, 50) + offset, 20, Color::White());
164  Point f = DrawPlaygroundPoint(point_f);
165  PlaygroundPoint point_g(Point(50, 150) + offset, 20, Color::White());
166  Point g = DrawPlaygroundPoint(point_g);
167  Path path = PathBuilder{}
168  .MoveTo(a)
169  .LineTo(b)
170  .LineTo(c)
171  .LineTo(d)
172  .Close()
173  .MoveTo(e)
174  .LineTo(f)
175  .LineTo(g)
176  .Close()
177  .TakePath();
178 
179  Entity entity;
180  entity.SetTransform(Matrix::MakeScale(GetContentScale()));
181  auto contents = std::make_unique<SolidColorContents>();
182  std::unique_ptr<Geometry> geom = Geometry::MakeStrokePath(path, 20.0);
183  contents->SetGeometry(geom.get());
184  contents->SetColor(Color::Red());
185  entity.SetContents(std::move(contents));
186 
187  return entity.Render(context, pass);
188  };
189  ASSERT_TRUE(OpenPlaygroundHere(callback));
190 }

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() [409/497]

impeller::testing::TEST_P ( EntityTest  ,
YUVToRGBFilter   
)

Definition at line 1653 of file entity_unittests.cc.

1653  {
1654  if (GetParam() == PlaygroundBackend::kOpenGLES) {
1655  // TODO(114588) : Support YUV to RGB filter on OpenGLES backend.
1656  GTEST_SKIP()
1657  << "YUV to RGB filter is not supported on OpenGLES backend yet.";
1658  }
1659 
1660  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
1661  YUVColorSpace yuv_color_space_array[2]{YUVColorSpace::kBT601FullRange,
1662  YUVColorSpace::kBT601LimitedRange};
1663  for (int i = 0; i < 2; i++) {
1664  auto yuv_color_space = yuv_color_space_array[i];
1665  auto textures =
1666  CreateTestYUVTextures(GetContext().get(), yuv_color_space);
1667  auto filter_contents = FilterContents::MakeYUVToRGBFilter(
1668  textures[0], textures[1], yuv_color_space);
1669  Entity filter_entity;
1670  filter_entity.SetContents(filter_contents);
1671  auto snapshot = filter_contents->RenderToSnapshot(context, filter_entity);
1672 
1673  Entity entity;
1674  auto contents = TextureContents::MakeRect(Rect::MakeLTRB(0, 0, 256, 256));
1675  contents->SetTexture(snapshot->texture);
1676  contents->SetSourceRect(Rect::MakeSize(snapshot->texture->GetSize()));
1677  entity.SetContents(contents);
1678  entity.SetTransform(
1679  Matrix::MakeTranslation({static_cast<Scalar>(100 + 400 * i), 300}));
1680  entity.Render(context, pass);
1681  }
1682  return true;
1683  };
1684  ASSERT_TRUE(OpenPlaygroundHere(callback));
1685 }
static std::vector< std::shared_ptr< Texture > > CreateTestYUVTextures(Context *context, YUVColorSpace yuv_color_space)
YUVColorSpace
Definition: color.h:54

References CreateTestYUVTextures(), impeller::kBT601FullRange, impeller::kBT601LimitedRange, impeller::kOpenGLES, impeller::TRect< Scalar >::MakeLTRB(), impeller::TextureContents::MakeRect(), impeller::TRect< Scalar >::MakeSize(), impeller::Matrix::MakeTranslation(), impeller::FilterContents::MakeYUVToRGBFilter(), impeller::Entity::Render(), impeller::Entity::SetContents(), and impeller::Entity::SetTransform().

◆ TEST_P() [410/497]

impeller::testing::TEST_P ( GaussianBlurFilterContentsTest  ,
CalculateUVsSimple   
)

Definition at line 334 of file gaussian_blur_filter_contents_unittests.cc.

334  {
335  std::shared_ptr<Texture> texture = MakeTexture(ISize(100, 100));
336  auto filter_input = FilterInput::Make(texture);
337  Entity entity;
338  Quad uvs = GaussianBlurFilterContents::CalculateUVs(
339  filter_input, entity, Rect::MakeSize(ISize(100, 100)), ISize(100, 100));
340  std::optional<Rect> uvs_bounds = Rect::MakePointBounds(uvs);
341  EXPECT_TRUE(uvs_bounds.has_value());
342  if (uvs_bounds.has_value()) {
343  EXPECT_TRUE(RectNear(uvs_bounds.value(), Rect::MakeXYWH(0, 0, 1, 1)));
344  }
345 }

References impeller::GaussianBlurFilterContents::CalculateUVs(), impeller::FilterInput::Make(), impeller::TRect< Scalar >::MakePointBounds(), impeller::TRect< Scalar >::MakeSize(), impeller::TRect< Scalar >::MakeXYWH(), RectNear(), and uvs.

◆ TEST_P() [411/497]

impeller::testing::TEST_P ( GaussianBlurFilterContentsTest  ,
CoverageWithEffectTransform   
)

Definition at line 186 of file gaussian_blur_filter_contents_unittests.cc.

186  {
187  Matrix effect_transform = Matrix::MakeScale({2.0, 2.0, 1.0});
188  fml::StatusOr<Scalar> sigma_radius_1 =
189  CalculateSigmaForBlurRadius(1.0, effect_transform);
190  ASSERT_TRUE(sigma_radius_1.ok());
191  GaussianBlurFilterContents contents(
192  /*sigma_x=*/sigma_radius_1.value(),
193  /*sigma_y=*/sigma_radius_1.value(), Entity::TileMode::kDecal,
194  FilterContents::BlurStyle::kNormal, /*mask_geometry=*/nullptr);
195  std::shared_ptr<Texture> texture = MakeTexture(ISize(100, 100));
196  FilterInput::Vector inputs = {FilterInput::Make(texture)};
197  Entity entity;
198  entity.SetTransform(Matrix::MakeTranslation({100, 100, 0}));
199  std::optional<Rect> coverage =
200  contents.GetFilterCoverage(inputs, entity, effect_transform);
201  EXPECT_TRUE(coverage.has_value());
202  if (coverage.has_value()) {
203  EXPECT_RECT_NEAR(coverage.value(),
204  Rect::MakeLTRB(100 - 1, 100 - 1, 200 + 1, 200 + 1));
205  }
206 }

References EXPECT_RECT_NEAR, impeller::GaussianBlurFilterContents::GetFilterCoverage(), impeller::Entity::kDecal, impeller::FilterContents::kNormal, impeller::FilterInput::Make(), impeller::TRect< Scalar >::MakeLTRB(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeTranslation(), and impeller::Entity::SetTransform().

◆ TEST_P() [412/497]

impeller::testing::TEST_P ( GaussianBlurFilterContentsTest  ,
CoverageWithTexture   
)

Definition at line 165 of file gaussian_blur_filter_contents_unittests.cc.

165  {
166  fml::StatusOr<Scalar> sigma_radius_1 =
167  CalculateSigmaForBlurRadius(1.0, Matrix());
168  ASSERT_TRUE(sigma_radius_1.ok());
169  GaussianBlurFilterContents contents(
170  /*sigma_X=*/sigma_radius_1.value(),
171  /*sigma_y=*/sigma_radius_1.value(), Entity::TileMode::kDecal,
172  FilterContents::BlurStyle::kNormal, /*mask_geometry=*/nullptr);
173  std::shared_ptr<Texture> texture = MakeTexture(ISize(100, 100));
174  FilterInput::Vector inputs = {FilterInput::Make(texture)};
175  Entity entity;
176  entity.SetTransform(Matrix::MakeTranslation({100, 100, 0}));
177  std::optional<Rect> coverage =
178  contents.GetFilterCoverage(inputs, entity, /*effect_transform=*/Matrix());
179 
180  EXPECT_TRUE(coverage.has_value());
181  if (coverage.has_value()) {
182  EXPECT_RECT_NEAR(coverage.value(), Rect::MakeLTRB(99, 99, 201, 201));
183  }
184 }

References EXPECT_RECT_NEAR, impeller::GaussianBlurFilterContents::GetFilterCoverage(), impeller::Entity::kDecal, impeller::FilterContents::kNormal, impeller::FilterInput::Make(), impeller::TRect< Scalar >::MakeLTRB(), impeller::Matrix::MakeTranslation(), and impeller::Entity::SetTransform().

◆ TEST_P() [413/497]

impeller::testing::TEST_P ( GaussianBlurFilterContentsTest  ,
RenderCoverageMatchesGetCoverage   
)

Definition at line 238 of file gaussian_blur_filter_contents_unittests.cc.

238  {
239  std::shared_ptr<Texture> texture = MakeTexture(ISize(100, 100));
240  fml::StatusOr<Scalar> sigma_radius_1 =
241  CalculateSigmaForBlurRadius(1.0, Matrix());
242  ASSERT_TRUE(sigma_radius_1.ok());
243  auto contents = std::make_unique<GaussianBlurFilterContents>(
244  sigma_radius_1.value(), sigma_radius_1.value(), Entity::TileMode::kDecal,
245  FilterContents::BlurStyle::kNormal, /*mask_geometry=*/nullptr);
246  contents->SetInputs({FilterInput::Make(texture)});
247  std::shared_ptr<ContentContext> renderer = GetContentContext();
248 
249  Entity entity;
250  std::optional<Entity> result =
251  contents->GetEntity(*renderer, entity, /*coverage_hint=*/{});
252  EXPECT_TRUE(result.has_value());
253  if (result.has_value()) {
254  EXPECT_EQ(result.value().GetBlendMode(), BlendMode::kSourceOver);
255  std::optional<Rect> result_coverage = result.value().GetCoverage();
256  std::optional<Rect> contents_coverage = contents->GetCoverage(entity);
257  EXPECT_TRUE(result_coverage.has_value());
258  EXPECT_TRUE(contents_coverage.has_value());
259  if (result_coverage.has_value() && contents_coverage.has_value()) {
260  EXPECT_TRUE(RectNear(contents_coverage.value(),
261  Rect::MakeLTRB(-1, -1, 101, 101)));
262  EXPECT_TRUE(
263  RectNear(result_coverage.value(), Rect::MakeLTRB(-1, -1, 101, 101)));
264  }
265  }
266 }

References impeller::Entity::kDecal, impeller::FilterContents::kNormal, impeller::kSourceOver, impeller::FilterInput::Make(), impeller::TRect< Scalar >::MakeLTRB(), and RectNear().

◆ TEST_P() [414/497]

impeller::testing::TEST_P ( GaussianBlurFilterContentsTest  ,
RenderCoverageMatchesGetCoverageRotated   
)

Definition at line 301 of file gaussian_blur_filter_contents_unittests.cc.

302  {
303  std::shared_ptr<Texture> texture = MakeTexture(ISize(400, 300));
304  fml::StatusOr<Scalar> sigma_radius_1 =
305  CalculateSigmaForBlurRadius(1.0, Matrix());
306  auto contents = std::make_unique<GaussianBlurFilterContents>(
307  sigma_radius_1.value(), sigma_radius_1.value(), Entity::TileMode::kDecal,
308  FilterContents::BlurStyle::kNormal, /*mask_geometry=*/nullptr);
309  contents->SetInputs({FilterInput::Make(texture)});
310  std::shared_ptr<ContentContext> renderer = GetContentContext();
311 
312  Entity entity;
313  // Rotate around the top left corner, then push it over to (100, 100).
314  entity.SetTransform(Matrix::MakeTranslation({400, 100, 0}) *
315  Matrix::MakeRotationZ(Degrees(90.0)));
316  std::optional<Entity> result =
317  contents->GetEntity(*renderer, entity, /*coverage_hint=*/{});
318  EXPECT_TRUE(result.has_value());
319  if (result.has_value()) {
320  EXPECT_EQ(result.value().GetBlendMode(), BlendMode::kSourceOver);
321  std::optional<Rect> result_coverage = result.value().GetCoverage();
322  std::optional<Rect> contents_coverage = contents->GetCoverage(entity);
323  EXPECT_TRUE(result_coverage.has_value());
324  EXPECT_TRUE(contents_coverage.has_value());
325  if (result_coverage.has_value() && contents_coverage.has_value()) {
326  EXPECT_TRUE(RectNear(contents_coverage.value(),
327  Rect::MakeLTRB(99, 99, 401, 501)));
328  EXPECT_TRUE(
329  RectNear(result_coverage.value(), Rect::MakeLTRB(99, 99, 401, 501)));
330  }
331  }
332 }

References impeller::Entity::kDecal, impeller::FilterContents::kNormal, impeller::kSourceOver, impeller::FilterInput::Make(), impeller::TRect< Scalar >::MakeLTRB(), impeller::Matrix::MakeRotationZ(), impeller::Matrix::MakeTranslation(), RectNear(), and impeller::Entity::SetTransform().

◆ TEST_P() [415/497]

impeller::testing::TEST_P ( GaussianBlurFilterContentsTest  ,
RenderCoverageMatchesGetCoverageTranslate   
)

Definition at line 268 of file gaussian_blur_filter_contents_unittests.cc.

269  {
270  std::shared_ptr<Texture> texture = MakeTexture(ISize(100, 100));
271  fml::StatusOr<Scalar> sigma_radius_1 =
272  CalculateSigmaForBlurRadius(1.0, Matrix());
273  ASSERT_TRUE(sigma_radius_1.ok());
274  auto contents = std::make_unique<GaussianBlurFilterContents>(
275  sigma_radius_1.value(), sigma_radius_1.value(), Entity::TileMode::kDecal,
276  FilterContents::BlurStyle::kNormal, /*mask_geometry=*/nullptr);
277  contents->SetInputs({FilterInput::Make(texture)});
278  std::shared_ptr<ContentContext> renderer = GetContentContext();
279 
280  Entity entity;
281  entity.SetTransform(Matrix::MakeTranslation({100, 200, 0}));
282  std::optional<Entity> result =
283  contents->GetEntity(*renderer, entity, /*coverage_hint=*/{});
284 
285  EXPECT_TRUE(result.has_value());
286  if (result.has_value()) {
287  EXPECT_EQ(result.value().GetBlendMode(), BlendMode::kSourceOver);
288  std::optional<Rect> result_coverage = result.value().GetCoverage();
289  std::optional<Rect> contents_coverage = contents->GetCoverage(entity);
290  EXPECT_TRUE(result_coverage.has_value());
291  EXPECT_TRUE(contents_coverage.has_value());
292  if (result_coverage.has_value() && contents_coverage.has_value()) {
293  EXPECT_TRUE(RectNear(contents_coverage.value(),
294  Rect::MakeLTRB(99, 199, 201, 301)));
295  EXPECT_TRUE(
296  RectNear(result_coverage.value(), Rect::MakeLTRB(99, 199, 201, 301)));
297  }
298  }
299 }

References impeller::Entity::kDecal, impeller::FilterContents::kNormal, impeller::kSourceOver, impeller::FilterInput::Make(), impeller::TRect< Scalar >::MakeLTRB(), impeller::Matrix::MakeTranslation(), RectNear(), and impeller::Entity::SetTransform().

◆ TEST_P() [416/497]

impeller::testing::TEST_P ( GaussianBlurFilterContentsTest  ,
TextureContentsWithDestinationRect   
)

Definition at line 347 of file gaussian_blur_filter_contents_unittests.cc.

347  {
348  std::shared_ptr<Texture> texture = MakeTexture(ISize(100, 100));
349  auto texture_contents = std::make_shared<TextureContents>();
350  texture_contents->SetSourceRect(Rect::MakeSize(texture->GetSize()));
351  texture_contents->SetTexture(texture);
352  texture_contents->SetDestinationRect(Rect::MakeXYWH(
353  50, 40, texture->GetSize().width, texture->GetSize().height));
354 
355  fml::StatusOr<Scalar> sigma_radius_1 =
356  CalculateSigmaForBlurRadius(1.0, Matrix());
357  auto contents = std::make_unique<GaussianBlurFilterContents>(
358  sigma_radius_1.value(), sigma_radius_1.value(), Entity::TileMode::kDecal,
359  FilterContents::BlurStyle::kNormal, /*mask_geometry=*/nullptr);
360  contents->SetInputs({FilterInput::Make(texture_contents)});
361  std::shared_ptr<ContentContext> renderer = GetContentContext();
362 
363  Entity entity;
364  std::optional<Entity> result =
365  contents->GetEntity(*renderer, entity, /*coverage_hint=*/{});
366  EXPECT_TRUE(result.has_value());
367  if (result.has_value()) {
368  EXPECT_EQ(result.value().GetBlendMode(), BlendMode::kSourceOver);
369  std::optional<Rect> result_coverage = result.value().GetCoverage();
370  std::optional<Rect> contents_coverage = contents->GetCoverage(entity);
371  EXPECT_TRUE(result_coverage.has_value());
372  EXPECT_TRUE(contents_coverage.has_value());
373  if (result_coverage.has_value() && contents_coverage.has_value()) {
374  EXPECT_TRUE(RectNear(result_coverage.value(), contents_coverage.value()));
375  EXPECT_TRUE(RectNear(result_coverage.value(),
376  Rect::MakeLTRB(49.f, 39.f, 151.f, 141.f)));
377  }
378  }
379 }

References impeller::Entity::kDecal, impeller::FilterContents::kNormal, impeller::kSourceOver, impeller::FilterInput::Make(), impeller::TRect< Scalar >::MakeLTRB(), impeller::TRect< Scalar >::MakeSize(), impeller::TRect< Scalar >::MakeXYWH(), and RectNear().

◆ TEST_P() [417/497]

impeller::testing::TEST_P ( GaussianBlurFilterContentsTest  ,
TextureContentsWithDestinationRectScaled   
)

Definition at line 381 of file gaussian_blur_filter_contents_unittests.cc.

382  {
383  std::shared_ptr<Texture> texture = MakeTexture(ISize(100, 100));
384  auto texture_contents = std::make_shared<TextureContents>();
385  texture_contents->SetSourceRect(Rect::MakeSize(texture->GetSize()));
386  texture_contents->SetTexture(texture);
387  texture_contents->SetDestinationRect(Rect::MakeXYWH(
388  50, 40, texture->GetSize().width, texture->GetSize().height));
389 
390  fml::StatusOr<Scalar> sigma_radius_1 =
391  CalculateSigmaForBlurRadius(1.0, Matrix());
392  auto contents = std::make_unique<GaussianBlurFilterContents>(
393  sigma_radius_1.value(), sigma_radius_1.value(), Entity::TileMode::kDecal,
394  FilterContents::BlurStyle::kNormal,
395  /*mask_geometry=*/nullptr);
396  contents->SetInputs({FilterInput::Make(texture_contents)});
397  std::shared_ptr<ContentContext> renderer = GetContentContext();
398 
399  Entity entity;
400  entity.SetTransform(Matrix::MakeScale({2.0, 2.0, 1.0}));
401  std::optional<Entity> result =
402  contents->GetEntity(*renderer, entity, /*coverage_hint=*/{});
403  EXPECT_TRUE(result.has_value());
404  if (result.has_value()) {
405  EXPECT_EQ(result.value().GetBlendMode(), BlendMode::kSourceOver);
406  std::optional<Rect> result_coverage = result.value().GetCoverage();
407  std::optional<Rect> contents_coverage = contents->GetCoverage(entity);
408  EXPECT_TRUE(result_coverage.has_value());
409  EXPECT_TRUE(contents_coverage.has_value());
410  if (result_coverage.has_value() && contents_coverage.has_value()) {
411  EXPECT_TRUE(RectNear(result_coverage.value(), contents_coverage.value()));
412  // Scaling a blurred entity doesn't seem to scale the blur radius linearly
413  // when comparing results with rrect_blur. That's why this is not
414  // Rect::MakeXYWH(98.f, 78.f, 204.0f, 204.f).
415  EXPECT_TRUE(RectNear(contents_coverage.value(),
416  Rect::MakeXYWH(94.f, 74.f, 212.0f, 212.f)));
417  }
418  }
419 }

References impeller::Entity::kDecal, impeller::FilterContents::kNormal, impeller::kSourceOver, impeller::FilterInput::Make(), impeller::Matrix::MakeScale(), impeller::TRect< Scalar >::MakeSize(), impeller::TRect< Scalar >::MakeXYWH(), RectNear(), and impeller::Entity::SetTransform().

◆ TEST_P() [418/497]

impeller::testing::TEST_P ( GaussianBlurFilterContentsTest  ,
TextureContentsWithEffectTransform   
)

Definition at line 421 of file gaussian_blur_filter_contents_unittests.cc.

421  {
422  Matrix effect_transform = Matrix::MakeScale({2.0, 2.0, 1.0});
423  std::shared_ptr<Texture> texture = MakeTexture(ISize(100, 100));
424  auto texture_contents = std::make_shared<TextureContents>();
425  texture_contents->SetSourceRect(Rect::MakeSize(texture->GetSize()));
426  texture_contents->SetTexture(texture);
427  texture_contents->SetDestinationRect(Rect::MakeXYWH(
428  50, 40, texture->GetSize().width, texture->GetSize().height));
429 
430  fml::StatusOr<Scalar> sigma_radius_1 =
431  CalculateSigmaForBlurRadius(1.0, effect_transform);
432  ASSERT_TRUE(sigma_radius_1.ok());
433  auto contents = std::make_unique<GaussianBlurFilterContents>(
434  sigma_radius_1.value(), sigma_radius_1.value(), Entity::TileMode::kDecal,
435  FilterContents::BlurStyle::kNormal, /*mask_geometry=*/nullptr);
436  contents->SetInputs({FilterInput::Make(texture_contents)});
437  contents->SetEffectTransform(effect_transform);
438  std::shared_ptr<ContentContext> renderer = GetContentContext();
439 
440  Entity entity;
441  std::optional<Entity> result =
442  contents->GetEntity(*renderer, entity, /*coverage_hint=*/{});
443  EXPECT_TRUE(result.has_value());
444  if (result.has_value()) {
445  EXPECT_EQ(result.value().GetBlendMode(), BlendMode::kSourceOver);
446  std::optional<Rect> result_coverage = result.value().GetCoverage();
447  std::optional<Rect> contents_coverage = contents->GetCoverage(entity);
448  EXPECT_TRUE(result_coverage.has_value());
449  EXPECT_TRUE(contents_coverage.has_value());
450  if (result_coverage.has_value() && contents_coverage.has_value()) {
451  EXPECT_TRUE(RectNear(result_coverage.value(), contents_coverage.value()));
452  EXPECT_TRUE(RectNear(contents_coverage.value(),
453  Rect::MakeXYWH(49.f, 39.f, 102.f, 102.f)));
454  }
455  }
456 }

References impeller::Entity::kDecal, impeller::FilterContents::kNormal, impeller::kSourceOver, impeller::FilterInput::Make(), impeller::Matrix::MakeScale(), impeller::TRect< Scalar >::MakeSize(), impeller::TRect< Scalar >::MakeXYWH(), and RectNear().

◆ TEST_P() [419/497]

impeller::testing::TEST_P ( HostBufferTest  ,
CanEmplace   
)

Definition at line 36 of file host_buffer_unittests.cc.

36  {
37  struct Length2 {
38  uint8_t pad[2];
39  };
40  static_assert(sizeof(Length2) == 2u);
41 
42  auto buffer = HostBuffer::Create(GetContext()->GetResourceAllocator(),
43  GetContext()->GetIdleWaiter());
44 
45  for (size_t i = 0; i < 12500; i++) {
46  auto view = buffer->Emplace(Length2{});
47  ASSERT_TRUE(view);
48  ASSERT_EQ(view.GetRange(), Range(i * sizeof(Length2), 2u));
49  }
50 }

References impeller::HostBuffer::Create().

◆ TEST_P() [420/497]

impeller::testing::TEST_P ( HostBufferTest  ,
CanEmplaceWithAlignment   
)

Definition at line 52 of file host_buffer_unittests.cc.

52  {
53  struct Length2 {
54  uint8_t pad[2];
55  };
56  static_assert(sizeof(Length2) == 2);
57  struct alignas(16) Align16 {
58  uint8_t pad[2];
59  };
60  static_assert(alignof(Align16) == 16);
61  static_assert(sizeof(Align16) == 16);
62 
63  auto buffer = HostBuffer::Create(GetContext()->GetResourceAllocator(),
64  GetContext()->GetIdleWaiter());
65  ASSERT_TRUE(buffer);
66 
67  {
68  auto view = buffer->Emplace(Length2{});
69  ASSERT_TRUE(view);
70  ASSERT_EQ(view.GetRange(), Range(0u, 2u));
71  }
72 
73  {
74  auto view = buffer->Emplace(Align16{});
75  ASSERT_TRUE(view);
76  ASSERT_EQ(view.GetRange().offset, 16u);
77  ASSERT_EQ(view.GetRange().length, 16u);
78  }
79  {
80  auto view = buffer->Emplace(Length2{});
81  ASSERT_TRUE(view);
82  ASSERT_EQ(view.GetRange(), Range(32u, 2u));
83  }
84 
85  {
86  auto view = buffer->Emplace(Align16{});
87  ASSERT_TRUE(view);
88  ASSERT_EQ(view.GetRange().offset, 48u);
89  ASSERT_EQ(view.GetRange().length, 16u);
90  }
91 }

References impeller::HostBuffer::Create().

◆ TEST_P() [421/497]

impeller::testing::TEST_P ( HostBufferTest  ,
EmplaceWithFailingAllocationDoesntCrash   
)

Definition at line 221 of file host_buffer_unittests.cc.

221  {
222  ScopedValidationDisable disable;
223  std::shared_ptr<FailingAllocator> allocator =
224  std::make_shared<FailingAllocator>(GetContext()->GetResourceAllocator());
225  auto buffer = HostBuffer::Create(allocator, GetContext()->GetIdleWaiter());
226 
227  auto view = buffer->Emplace(nullptr, kMagicFailingAllocation, 0);
228 
229  EXPECT_EQ(view.GetBuffer(), nullptr);
230  EXPECT_EQ(view.GetRange().offset, 0u);
231  EXPECT_EQ(view.GetRange().length, 0u);
232 }
static constexpr const size_t kMagicFailingAllocation

References impeller::HostBuffer::Create(), and kMagicFailingAllocation.

◆ TEST_P() [422/497]

impeller::testing::TEST_P ( HostBufferTest  ,
EmplaceWithProcIsAligned   
)

Definition at line 180 of file host_buffer_unittests.cc.

180  {
181  auto buffer = HostBuffer::Create(GetContext()->GetResourceAllocator(),
182  GetContext()->GetIdleWaiter());
183 
184  BufferView view = buffer->Emplace(std::array<char, 21>());
185  EXPECT_EQ(view.GetRange(), Range(0, 21));
186 
187  view = buffer->Emplace(64, 16, [](uint8_t*) {});
188  EXPECT_EQ(view.GetRange(), Range(32, 64));
189 }

References impeller::HostBuffer::Create(), and impeller::BufferView::GetRange().

◆ TEST_P() [423/497]

impeller::testing::TEST_P ( HostBufferTest  ,
EmplacingLargerThanBlockSizeCreatesOneOffBuffer   
)

Definition at line 135 of file host_buffer_unittests.cc.

135  {
136  auto buffer = HostBuffer::Create(GetContext()->GetResourceAllocator(),
137  GetContext()->GetIdleWaiter());
138 
139  // Emplace an amount larger than the block size, to verify that the host
140  // buffer does not create a buffer.
141  auto buffer_view = buffer->Emplace(nullptr, 1024000 + 10, 0);
142 
143  EXPECT_EQ(buffer->GetStateForTest().current_buffer, 0u);
144  EXPECT_EQ(buffer->GetStateForTest().current_frame, 0u);
145  EXPECT_EQ(buffer->GetStateForTest().total_buffer_count, 1u);
146 }

References buffer_view, and impeller::HostBuffer::Create().

◆ TEST_P() [424/497]

impeller::testing::TEST_P ( HostBufferTest  ,
EmplacingLargerThanBlockSizeCreatesOneOffBufferCallback   
)

Definition at line 121 of file host_buffer_unittests.cc.

122  {
123  auto buffer = HostBuffer::Create(GetContext()->GetResourceAllocator(),
124  GetContext()->GetIdleWaiter());
125 
126  // Emplace an amount larger than the block size, to verify that the host
127  // buffer does not create a buffer.
128  auto buffer_view = buffer->Emplace(1024000 + 10, 0, [](uint8_t* data) {});
129 
130  EXPECT_EQ(buffer->GetStateForTest().current_buffer, 0u);
131  EXPECT_EQ(buffer->GetStateForTest().current_frame, 0u);
132  EXPECT_EQ(buffer->GetStateForTest().total_buffer_count, 1u);
133 }

References buffer_view, impeller::HostBuffer::Create(), and data.

◆ TEST_P() [425/497]

impeller::testing::TEST_P ( HostBufferTest  ,
HostBufferInitialState   
)

Definition at line 93 of file host_buffer_unittests.cc.

93  {
94  auto buffer = HostBuffer::Create(GetContext()->GetResourceAllocator(),
95  GetContext()->GetIdleWaiter());
96 
97  EXPECT_EQ(buffer->GetStateForTest().current_buffer, 0u);
98  EXPECT_EQ(buffer->GetStateForTest().current_frame, 0u);
99  EXPECT_EQ(buffer->GetStateForTest().total_buffer_count, 1u);
100 }

References impeller::HostBuffer::Create().

◆ TEST_P() [426/497]

impeller::testing::TEST_P ( HostBufferTest  ,
IdleWaiter   
)

Definition at line 27 of file host_buffer_unittests.cc.

27  {
28  auto mock_idle_waiter = std::make_shared<MockIdleWaiter>();
29  {
30  auto buffer = HostBuffer::Create(GetContext()->GetResourceAllocator(),
31  mock_idle_waiter);
32  EXPECT_CALL(*mock_idle_waiter, WaitIdle());
33  }
34 }

References impeller::HostBuffer::Create().

◆ TEST_P() [427/497]

impeller::testing::TEST_P ( HostBufferTest  ,
ResetIncrementsFrameCounter   
)

Definition at line 102 of file host_buffer_unittests.cc.

102  {
103  auto buffer = HostBuffer::Create(GetContext()->GetResourceAllocator(),
104  GetContext()->GetIdleWaiter());
105 
106  EXPECT_EQ(buffer->GetStateForTest().current_frame, 0u);
107 
108  buffer->Reset();
109  EXPECT_EQ(buffer->GetStateForTest().current_frame, 1u);
110 
111  buffer->Reset();
112  EXPECT_EQ(buffer->GetStateForTest().current_frame, 2u);
113 
114  buffer->Reset();
115  EXPECT_EQ(buffer->GetStateForTest().current_frame, 3u);
116 
117  buffer->Reset();
118  EXPECT_EQ(buffer->GetStateForTest().current_frame, 0u);
119 }

References impeller::HostBuffer::Create().

◆ TEST_P() [428/497]

impeller::testing::TEST_P ( HostBufferTest  ,
UnusedBuffersAreDiscardedWhenResetting   
)

Definition at line 148 of file host_buffer_unittests.cc.

148  {
149  auto buffer = HostBuffer::Create(GetContext()->GetResourceAllocator(),
150  GetContext()->GetIdleWaiter());
151 
152  // Emplace two large allocations to force the allocation of a second buffer.
153  auto buffer_view_a = buffer->Emplace(1020000, 0, [](uint8_t* data) {});
154  auto buffer_view_b = buffer->Emplace(1020000, 0, [](uint8_t* data) {});
155 
156  EXPECT_EQ(buffer->GetStateForTest().current_buffer, 1u);
157  EXPECT_EQ(buffer->GetStateForTest().total_buffer_count, 2u);
158  EXPECT_EQ(buffer->GetStateForTest().current_frame, 0u);
159 
160  // Reset until we get back to this frame.
161  for (auto i = 0; i < 4; i++) {
162  buffer->Reset();
163  }
164 
165  EXPECT_EQ(buffer->GetStateForTest().current_buffer, 0u);
166  EXPECT_EQ(buffer->GetStateForTest().total_buffer_count, 2u);
167  EXPECT_EQ(buffer->GetStateForTest().current_frame, 0u);
168 
169  // Now when we reset, the buffer should get dropped.
170  // Reset until we get back to this frame.
171  for (auto i = 0; i < 4; i++) {
172  buffer->Reset();
173  }
174 
175  EXPECT_EQ(buffer->GetStateForTest().current_buffer, 0u);
176  EXPECT_EQ(buffer->GetStateForTest().total_buffer_count, 1u);
177  EXPECT_EQ(buffer->GetStateForTest().current_frame, 0u);
178 }

References impeller::HostBuffer::Create(), and data.

◆ TEST_P() [429/497]

impeller::testing::TEST_P ( MatrixFilterContentsTest  ,
RenderCoverageMatchesGetCoverageClippedSubpassScale   
)

Definition at line 175 of file matrix_filter_contents_unittests.cc.

176  {
177  std::shared_ptr<Texture> texture = MakeTexture(ISize(100, 100));
178  MatrixFilterContents contents;
179  contents.SetInputs({FilterInput::Make(texture)});
180  contents.SetMatrix(Matrix::MakeScale({3, 3, 1}));
181  contents.SetEffectTransform(Matrix::MakeScale({2, 2, 1}));
182  contents.SetRenderingMode(
183  Entity::RenderingMode::kSubpassAppendSnapshotTransform);
184 
185  Entity entity;
186  entity.SetTransform(Matrix::MakeTranslation({100, 200, 0}));
187 
188  std::shared_ptr<ContentContext> renderer = GetContentContext();
189  std::optional<Entity> result =
190  contents.GetEntity(*renderer, entity, /*coverage_hint=*/{});
191  expectRenderCoverageEqual(result, contents.GetCoverage(entity),
192  Rect::MakeXYWH(100, 200, 300, 300));
193 }

References impeller::FilterContents::GetCoverage(), impeller::FilterContents::GetEntity(), impeller::Entity::kSubpassAppendSnapshotTransform, impeller::FilterInput::Make(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeTranslation(), impeller::TRect< Scalar >::MakeXYWH(), impeller::FilterContents::SetEffectTransform(), impeller::FilterContents::SetInputs(), impeller::MatrixFilterContents::SetMatrix(), impeller::MatrixFilterContents::SetRenderingMode(), and impeller::Entity::SetTransform().

◆ TEST_P() [430/497]

impeller::testing::TEST_P ( MatrixFilterContentsTest  ,
RenderCoverageMatchesGetCoverageClippedSubpassTranslate   
)

Definition at line 138 of file matrix_filter_contents_unittests.cc.

139  {
140  std::shared_ptr<Texture> texture = MakeTexture(ISize(100, 100));
141  MatrixFilterContents contents;
142  contents.SetInputs({FilterInput::Make(texture)});
143  contents.SetMatrix(Matrix::MakeTranslation({50, 100, 0}));
144  contents.SetEffectTransform(Matrix::MakeScale({2, 2, 1}));
145  contents.SetRenderingMode(
146  Entity::RenderingMode::kSubpassAppendSnapshotTransform);
147 
148  Entity entity;
149  entity.SetTransform(Matrix::MakeTranslation({100, 200, 0}));
150 
151  std::shared_ptr<ContentContext> renderer = GetContentContext();
152  std::optional<Entity> result =
153  contents.GetEntity(*renderer, entity, /*coverage_hint=*/{});
154  expectRenderCoverageEqual(result, contents.GetCoverage(entity),
155  Rect::MakeXYWH(200, 400, 100, 100));
156 }

References impeller::FilterContents::GetCoverage(), impeller::FilterContents::GetEntity(), impeller::Entity::kSubpassAppendSnapshotTransform, impeller::FilterInput::Make(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeTranslation(), impeller::TRect< Scalar >::MakeXYWH(), impeller::FilterContents::SetEffectTransform(), impeller::FilterContents::SetInputs(), impeller::MatrixFilterContents::SetMatrix(), impeller::MatrixFilterContents::SetRenderingMode(), and impeller::Entity::SetTransform().

◆ TEST_P() [431/497]

impeller::testing::TEST_P ( MatrixFilterContentsTest  ,
RenderCoverageMatchesGetCoverageIdentity   
)

Definition at line 106 of file matrix_filter_contents_unittests.cc.

106  {
107  std::shared_ptr<Texture> texture = MakeTexture(ISize(100, 100));
108  MatrixFilterContents contents;
109  contents.SetInputs({FilterInput::Make(texture)});
110 
111  Entity entity;
112  entity.SetTransform(Matrix::MakeTranslation({100, 200, 0}));
113 
114  std::shared_ptr<ContentContext> renderer = GetContentContext();
115  std::optional<Entity> result =
116  contents.GetEntity(*renderer, entity, /*coverage_hint=*/{});
117  expectRenderCoverageEqual(result, contents.GetCoverage(entity),
118  Rect::MakeXYWH(100, 200, 100, 100));
119 }

References impeller::FilterContents::GetCoverage(), impeller::FilterContents::GetEntity(), impeller::FilterInput::Make(), impeller::Matrix::MakeTranslation(), impeller::TRect< Scalar >::MakeXYWH(), impeller::FilterContents::SetInputs(), and impeller::Entity::SetTransform().

◆ TEST_P() [432/497]

impeller::testing::TEST_P ( MatrixFilterContentsTest  ,
RenderCoverageMatchesGetCoverageScale   
)

Definition at line 158 of file matrix_filter_contents_unittests.cc.

158  {
159  std::shared_ptr<Texture> texture = MakeTexture(ISize(100, 100));
160  MatrixFilterContents contents;
161  contents.SetInputs({FilterInput::Make(texture)});
162  contents.SetMatrix(Matrix::MakeScale({3, 3, 1}));
163  contents.SetEffectTransform(Matrix::MakeScale({2, 2, 1}));
164 
165  Entity entity;
166  entity.SetTransform(Matrix::MakeTranslation({100, 200, 0}));
167 
168  std::shared_ptr<ContentContext> renderer = GetContentContext();
169  std::optional<Entity> result =
170  contents.GetEntity(*renderer, entity, /*coverage_hint=*/{});
171  expectRenderCoverageEqual(result, contents.GetCoverage(entity),
172  Rect::MakeXYWH(100, 200, 300, 300));
173 }

References impeller::FilterContents::GetCoverage(), impeller::FilterContents::GetEntity(), impeller::FilterInput::Make(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeTranslation(), impeller::TRect< Scalar >::MakeXYWH(), impeller::FilterContents::SetEffectTransform(), impeller::FilterContents::SetInputs(), impeller::MatrixFilterContents::SetMatrix(), and impeller::Entity::SetTransform().

◆ TEST_P() [433/497]

impeller::testing::TEST_P ( MatrixFilterContentsTest  ,
RenderCoverageMatchesGetCoverageSubpassScale   
)

Definition at line 195 of file matrix_filter_contents_unittests.cc.

195  {
196  std::shared_ptr<Texture> texture = MakeTexture(ISize(100, 100));
197  MatrixFilterContents contents;
198  contents.SetInputs({FilterInput::Make(texture)});
199  contents.SetMatrix(Matrix::MakeScale({3, 3, 1}));
200  contents.SetEffectTransform(Matrix::MakeScale({2, 2, 1}));
201  contents.SetRenderingMode(
202  Entity::RenderingMode::kSubpassPrependSnapshotTransform);
203 
204  Entity entity;
205  entity.SetTransform(Matrix::MakeTranslation({100, 200, 0}));
206 
207  std::shared_ptr<ContentContext> renderer = GetContentContext();
208  std::optional<Entity> result =
209  contents.GetEntity(*renderer, entity, /*coverage_hint=*/{});
210  expectRenderCoverageEqual(result, contents.GetCoverage(entity),
211  Rect::MakeXYWH(300, 600, 300, 300));
212 }

References impeller::FilterContents::GetCoverage(), impeller::FilterContents::GetEntity(), impeller::Entity::kSubpassPrependSnapshotTransform, impeller::FilterInput::Make(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeTranslation(), impeller::TRect< Scalar >::MakeXYWH(), impeller::FilterContents::SetEffectTransform(), impeller::FilterContents::SetInputs(), impeller::MatrixFilterContents::SetMatrix(), impeller::MatrixFilterContents::SetRenderingMode(), and impeller::Entity::SetTransform().

◆ TEST_P() [434/497]

impeller::testing::TEST_P ( MatrixFilterContentsTest  ,
RenderCoverageMatchesGetCoverageTranslate   
)

Definition at line 121 of file matrix_filter_contents_unittests.cc.

121  {
122  std::shared_ptr<Texture> texture = MakeTexture(ISize(100, 100));
123  MatrixFilterContents contents;
124  contents.SetInputs({FilterInput::Make(texture)});
125  contents.SetMatrix(Matrix::MakeTranslation({50, 100, 0}));
126  contents.SetEffectTransform(Matrix::MakeScale({2, 2, 1}));
127 
128  Entity entity;
129  entity.SetTransform(Matrix::MakeTranslation({100, 200, 0}));
130 
131  std::shared_ptr<ContentContext> renderer = GetContentContext();
132  std::optional<Entity> result =
133  contents.GetEntity(*renderer, entity, /*coverage_hint=*/{});
134  expectRenderCoverageEqual(result, contents.GetCoverage(entity),
135  Rect::MakeXYWH(150, 300, 100, 100));
136 }

References impeller::FilterContents::GetCoverage(), impeller::FilterContents::GetEntity(), impeller::FilterInput::Make(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeTranslation(), impeller::TRect< Scalar >::MakeXYWH(), impeller::FilterContents::SetEffectTransform(), impeller::FilterContents::SetInputs(), impeller::MatrixFilterContents::SetMatrix(), and impeller::Entity::SetTransform().

◆ TEST_P() [435/497]

impeller::testing::TEST_P ( PipelineCacheDataVKPlaygroundTest  ,
CanPersistAndRetrievePipelineCache   
)

Definition at line 98 of file pipeline_cache_data_vk_unittests.cc.

98  {
99  fml::ScopedTemporaryDirectory temp_dir;
100  const auto& surface_context = SurfaceContextVK::Cast(*GetContext());
101  const auto& context_vk = ContextVK::Cast(*surface_context.GetParent());
102  const auto& caps = CapabilitiesVK::Cast(*context_vk.GetCapabilities());
103 
104  {
105  auto cache = context_vk.GetDevice().createPipelineCacheUnique({});
106  ASSERT_EQ(cache.result, vk::Result::eSuccess);
107  ASSERT_FALSE(fml::FileExists(temp_dir.fd(), "flutter.impeller.vkcache"));
108  ASSERT_TRUE(PipelineCacheDataPersist(
109  temp_dir.fd(), caps.GetPhysicalDeviceProperties(), cache.value));
110  }
111  ASSERT_TRUE(fml::FileExists(temp_dir.fd(), "flutter.impeller.vkcache"));
112 
113  auto mapping = PipelineCacheDataRetrieve(temp_dir.fd(),
114  caps.GetPhysicalDeviceProperties());
115  ASSERT_NE(mapping, nullptr);
116  // Assert that the utility has stripped away the cache header giving us clean
117  // pipeline cache bootstrap information.
118  vk::PipelineCacheHeaderVersionOne vk_cache_header;
119  ASSERT_GE(mapping->GetSize(), sizeof(vk_cache_header));
120  std::memcpy(&vk_cache_header, mapping->GetMapping(), sizeof(vk_cache_header));
121  ASSERT_EQ(vk_cache_header.headerVersion,
122  vk::PipelineCacheHeaderVersion::eOne);
123 }
std::unique_ptr< fml::Mapping > PipelineCacheDataRetrieve(const fml::UniqueFD &cache_directory, const VkPhysicalDeviceProperties &props)
Retrieve the previously persisted pipeline cache data. This function provides integrity checks the Vu...
bool PipelineCacheDataPersist(const fml::UniqueFD &cache_directory, const VkPhysicalDeviceProperties &props, const vk::UniquePipelineCache &cache)
Persist the pipeline cache to a file in the given cache directory. This function performs integrity c...

References impeller::BackendCast< CapabilitiesVK, Capabilities >::Cast(), impeller::BackendCast< ContextVK, Context >::Cast(), impeller::BackendCast< SurfaceContextVK, Context >::Cast(), impeller::PipelineCacheDataPersist(), and impeller::PipelineCacheDataRetrieve().

◆ TEST_P() [436/497]

impeller::testing::TEST_P ( PipelineCacheDataVKPlaygroundTest  ,
IntegrityChecksArePerformedOnPersistedData   
)

Definition at line 125 of file pipeline_cache_data_vk_unittests.cc.

126  {
127  fml::ScopedTemporaryDirectory temp_dir;
128  const auto& surface_context = SurfaceContextVK::Cast(*GetContext());
129  const auto& context_vk = ContextVK::Cast(*surface_context.GetParent());
130  const auto& caps = CapabilitiesVK::Cast(*context_vk.GetCapabilities());
131 
132  {
133  auto cache = context_vk.GetDevice().createPipelineCacheUnique({});
134  ASSERT_EQ(cache.result, vk::Result::eSuccess);
135  ASSERT_FALSE(fml::FileExists(temp_dir.fd(), "flutter.impeller.vkcache"));
136  ASSERT_TRUE(PipelineCacheDataPersist(
137  temp_dir.fd(), caps.GetPhysicalDeviceProperties(), cache.value));
138  }
139  ASSERT_TRUE(fml::FileExists(temp_dir.fd(), "flutter.impeller.vkcache"));
140  auto incompatible_caps = caps.GetPhysicalDeviceProperties();
141  // Simulate a driver version bump.
142  incompatible_caps.driverVersion =
143  caps.GetPhysicalDeviceProperties().driverVersion + 1u;
144  auto mapping = PipelineCacheDataRetrieve(temp_dir.fd(), incompatible_caps);
145  ASSERT_EQ(mapping, nullptr);
146 }

References impeller::BackendCast< CapabilitiesVK, Capabilities >::Cast(), impeller::BackendCast< ContextVK, Context >::Cast(), impeller::BackendCast< SurfaceContextVK, Context >::Cast(), impeller::PipelineCacheDataPersist(), and impeller::PipelineCacheDataRetrieve().

◆ TEST_P() [437/497]

impeller::testing::TEST_P ( RendererDartTest  ,
CanCreateRenderPassAndSubmit   
)

Definition at line 299 of file renderer_dart_unittests.cc.

299  {
300  ASSERT_TRUE(RenderDartToPlayground("canCreateRenderPassAndSubmit"));
301 }

◆ TEST_P() [438/497]

impeller::testing::TEST_P ( RendererDartTest  ,
CanCreateShaderLibrary   
)

Definition at line 291 of file renderer_dart_unittests.cc.

291  {
292  ASSERT_TRUE(RunDartFunction("canCreateShaderLibrary"));
293 }

◆ TEST_P() [439/497]

impeller::testing::TEST_P ( RendererDartTest  ,
CanInstantiateFlutterGPUContext   
)

These test entries correspond to Dart functions located in flutter/impeller/fixtures/dart_tests.dart

Definition at line 287 of file renderer_dart_unittests.cc.

287  {
288  ASSERT_TRUE(RunDartFunction("instantiateDefaultContext"));
289 }

◆ TEST_P() [440/497]

impeller::testing::TEST_P ( RendererDartTest  ,
CanReflectUniformStructs   
)

Definition at line 295 of file renderer_dart_unittests.cc.

295  {
296  ASSERT_TRUE(RunDartFunction("canReflectUniformStructs"));
297 }

◆ TEST_P() [441/497]

impeller::testing::TEST_P ( RendererDartTest  ,
CanRunDartInPlaygroundFrame   
)

Definition at line 272 of file renderer_dart_unittests.cc.

272  {
273  SinglePassCallback callback = [&](RenderPass& pass) {
274  ImGui::Begin("Dart test", nullptr);
275  ImGui::Text(
276  "This test executes Dart code during the playground frame callback.");
277  ImGui::End();
278 
279  return RunDartFunction("sayHi");
280  };
281  ASSERT_TRUE(OpenPlaygroundHere(callback));
282 }

◆ TEST_P() [442/497]

impeller::testing::TEST_P ( RendererTest  ,
ArrayUniforms   
)

Definition at line 1017 of file renderer_unittests.cc.

1017  {
1018  using VS = ArrayVertexShader;
1019  using FS = ArrayFragmentShader;
1020 
1021  auto context = GetContext();
1022  auto pipeline_descriptor =
1023  PipelineBuilder<VS, FS>::MakeDefaultPipelineDescriptor(*context);
1024  ASSERT_TRUE(pipeline_descriptor.has_value());
1025  pipeline_descriptor->SetSampleCount(SampleCount::kCount4);
1026  pipeline_descriptor->SetStencilAttachmentDescriptors(std::nullopt);
1027  auto pipeline =
1028  context->GetPipelineLibrary()->GetPipeline(pipeline_descriptor).Get();
1029  ASSERT_TRUE(pipeline && pipeline->IsValid());
1030 
1031  auto host_buffer = HostBuffer::Create(context->GetResourceAllocator(),
1032  context->GetIdleWaiter());
1033  SinglePassCallback callback = [&](RenderPass& pass) {
1034  auto size = pass.GetRenderTargetSize();
1035 
1036  pass.SetPipeline(pipeline);
1037  pass.SetCommandLabel("Google Dots");
1038  VertexBufferBuilder<VS::PerVertexData> builder;
1039  builder.AddVertices({{Point()},
1040  {Point(0, size.height)},
1041  {Point(size.width, 0)},
1042  {Point(size.width, 0)},
1043  {Point(0, size.height)},
1044  {Point(size.width, size.height)}});
1045  pass.SetVertexBuffer(builder.CreateVertexBuffer(*host_buffer));
1046 
1047  VS::FrameInfo frame_info;
1048  EXPECT_EQ(pass.GetOrthographicTransform(), Matrix::MakeOrthographic(size));
1049  frame_info.mvp =
1050  pass.GetOrthographicTransform() * Matrix::MakeScale(GetContentScale());
1051  VS::BindFrameInfo(pass, host_buffer->EmplaceUniform(frame_info));
1052 
1053  auto time = GetSecondsElapsed();
1054  auto y_pos = [&time](float x) {
1055  return 400 + 10 * std::cos(time * 5 + x / 6);
1056  };
1057 
1058  FS::FragInfo fs_uniform = {
1059  .circle_positions = {Point(430, y_pos(0)), Point(480, y_pos(1)),
1060  Point(530, y_pos(2)), Point(580, y_pos(3))},
1061  .colors = {Color::MakeRGBA8(66, 133, 244, 255),
1062  Color::MakeRGBA8(219, 68, 55, 255),
1063  Color::MakeRGBA8(244, 180, 0, 255),
1064  Color::MakeRGBA8(15, 157, 88, 255)},
1065  };
1066  FS::BindFragInfo(pass, host_buffer->EmplaceUniform(fs_uniform));
1067 
1068  pass.Draw();
1069  host_buffer->Reset();
1070  return true;
1071  };
1072  OpenPlaygroundHere(callback);
1073 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), impeller::HostBuffer::Create(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::CreateVertexBuffer(), impeller::kCount4, impeller::PipelineBuilder< VertexShader_, FragmentShader_ >::MakeDefaultPipelineDescriptor(), impeller::Matrix::MakeOrthographic(), impeller::Color::MakeRGBA8(), impeller::Matrix::MakeScale(), and x.

◆ TEST_P() [443/497]

impeller::testing::TEST_P ( RendererTest  ,
BabysFirstTriangle   
)

Definition at line 122 of file renderer_unittests.cc.

122  {
123  auto context = GetContext();
124  ASSERT_TRUE(context);
125 
126  // Declare a shorthand for the shaders we are going to use.
127  using VS = BabyVertexShader;
128  using FS = BabyFragmentShader;
129 
130  // Create a pipeline descriptor that uses the shaders together and default
131  // initializes the fixed function state.
132  //
133  // If the vertex shader outputs disagree with the fragment shader inputs, this
134  // will be a compile time error.
135  auto desc = PipelineBuilder<VS, FS>::MakeDefaultPipelineDescriptor(*context);
136  ASSERT_TRUE(desc.has_value());
137 
138  // Modify the descriptor for our environment. This is specific to our test.
139  desc->SetSampleCount(SampleCount::kCount4);
140  desc->SetStencilAttachmentDescriptors(std::nullopt);
141 
142  // Create a pipeline from our descriptor. This is expensive to do. So just do
143  // it once.
144  auto pipeline = context->GetPipelineLibrary()->GetPipeline(desc).Get();
145 
146  // Create a host side buffer to build the vertex and uniform information.
147  auto host_buffer = HostBuffer::Create(context->GetResourceAllocator(),
148  context->GetIdleWaiter());
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  context->GetIdleWaiter());
170  FS::BindFragInfo(pass, host_buffer->EmplaceUniform(frag_info));
171 
172  return pass.Draw().ok();
173  };
174  OpenPlaygroundHere(callback);
175 }

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() [444/497]

impeller::testing::TEST_P ( RendererTest  ,
BindingNullTexturesDoesNotCrash   
)

Definition at line 1613 of file renderer_unittests.cc.

1613  {
1614  using FS = BoxFadeFragmentShader;
1615 
1616  auto context = GetContext();
1617  raw_ptr<const Sampler> sampler = context->GetSamplerLibrary()->GetSampler({});
1618  auto command_buffer = context->CreateCommandBuffer();
1619 
1620  RenderTargetAllocator allocator(context->GetResourceAllocator());
1621  RenderTarget target = allocator.CreateOffscreen(*context, {1, 1}, 1);
1622 
1623  auto pass = command_buffer->CreateRenderPass(target);
1624  EXPECT_FALSE(FS::BindContents2(*pass, nullptr, sampler));
1625 }

References impeller::RenderTargetAllocator::CreateOffscreen().

◆ TEST_P() [445/497]

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 = render_target.GetColorAttachment(0).resolve_texture;
27  auto& texture_vk = TextureVK::Cast(*resolve_texture);
28 
29  EXPECT_EQ(texture_vk.GetCachedFramebuffer(), nullptr);
30  EXPECT_EQ(texture_vk.GetCachedRenderPass(), nullptr);
31 
32  auto buffer = GetContext()->CreateCommandBuffer();
33  auto render_pass = buffer->CreateRenderPass(render_target);
34 
35  EXPECT_NE(texture_vk.GetCachedFramebuffer(), nullptr);
36  EXPECT_NE(texture_vk.GetCachedRenderPass(), nullptr);
37 
38  render_pass->EncodeCommands();
39  GetContext()->GetCommandQueue()->Submit({buffer});
40 
41  // Can be reused without error.
42  auto buffer_2 = GetContext()->CreateCommandBuffer();
43  auto render_pass_2 = buffer_2->CreateRenderPass(render_target);
44 
45  EXPECT_TRUE(render_pass_2->EncodeCommands());
46  EXPECT_TRUE(GetContext()->GetCommandQueue()->Submit({buffer_2}).ok());
47 }

References impeller::BackendCast< TextureVK, Texture >::Cast(), and impeller::kVulkan.

◆ TEST_P() [446/497]

impeller::testing::TEST_P ( RendererTest  ,
CanBlitTextureToBuffer   
)

Definition at line 634 of file renderer_unittests.cc.

634  {
635  if (GetBackend() == PlaygroundBackend::kOpenGLES) {
636  GTEST_SKIP() << "Mipmap test shader not supported on GLES.";
637  }
638  auto context = GetContext();
639  ASSERT_TRUE(context);
640 
641  using VS = MipmapsVertexShader;
642  using FS = MipmapsFragmentShader;
643  auto desc = PipelineBuilder<VS, FS>::MakeDefaultPipelineDescriptor(*context);
644  ASSERT_TRUE(desc.has_value());
645  desc->SetSampleCount(SampleCount::kCount4);
646  desc->SetStencilAttachmentDescriptors(std::nullopt);
647  auto mipmaps_pipeline =
648  context->GetPipelineLibrary()->GetPipeline(std::move(desc)).Get();
649  ASSERT_TRUE(mipmaps_pipeline);
650 
651  auto bridge = CreateTextureForFixture("bay_bridge.jpg");
652  auto boston = CreateTextureForFixture("boston.jpg");
653  ASSERT_TRUE(bridge && boston);
654  raw_ptr<const Sampler> sampler = context->GetSamplerLibrary()->GetSampler({});
655  ASSERT_TRUE(sampler);
656 
657  TextureDescriptor texture_desc;
658  texture_desc.storage_mode = StorageMode::kHostVisible;
659  texture_desc.format = PixelFormat::kR8G8B8A8UNormInt;
660  texture_desc.size = bridge->GetTextureDescriptor().size;
661  texture_desc.mip_count = 1u;
662  texture_desc.usage = TextureUsage::kRenderTarget |
663  TextureUsage::kShaderWrite | TextureUsage::kShaderRead;
664  DeviceBufferDescriptor device_buffer_desc;
665  device_buffer_desc.storage_mode = StorageMode::kHostVisible;
666  device_buffer_desc.size =
667  bridge->GetTextureDescriptor().GetByteSizeOfBaseMipLevel();
668  auto device_buffer =
669  context->GetResourceAllocator()->CreateBuffer(device_buffer_desc);
670 
671  // Vertex buffer.
672  VertexBufferBuilder<VS::PerVertexData> vertex_builder;
673  vertex_builder.SetLabel("Box");
674  auto size = Point(boston->GetSize());
675  vertex_builder.AddVertices({
676  {{0, 0}, {0.0, 0.0}}, // 1
677  {{size.x, 0}, {1.0, 0.0}}, // 2
678  {{size.x, size.y}, {1.0, 1.0}}, // 3
679  {{0, 0}, {0.0, 0.0}}, // 1
680  {{size.x, size.y}, {1.0, 1.0}}, // 3
681  {{0, size.y}, {0.0, 1.0}}, // 4
682  });
683  auto vertex_buffer =
684  vertex_builder.CreateVertexBuffer(*context->GetResourceAllocator());
685  ASSERT_TRUE(vertex_buffer);
686 
687  auto host_buffer = HostBuffer::Create(context->GetResourceAllocator(),
688  context->GetIdleWaiter());
689  Playground::RenderCallback callback = [&](RenderTarget& render_target) {
690  {
691  auto buffer = context->CreateCommandBuffer();
692  if (!buffer) {
693  return false;
694  }
695  buffer->SetLabel("Playground Command Buffer");
696  auto pass = buffer->CreateBlitPass();
697  if (!pass) {
698  return false;
699  }
700  pass->SetLabel("Playground Blit Pass");
701 
702  // Blit `bridge` to the top left corner of the texture.
703  pass->AddCopy(bridge, device_buffer);
704  pass->EncodeCommands();
705 
706  if (!context->GetCommandQueue()->Submit({buffer}).ok()) {
707  return false;
708  }
709  }
710 
711  {
712  auto buffer = context->CreateCommandBuffer();
713  if (!buffer) {
714  return false;
715  }
716  buffer->SetLabel("Playground Command Buffer");
717 
718  auto pass = buffer->CreateRenderPass(render_target);
719  if (!pass) {
720  return false;
721  }
722  pass->SetLabel("Playground Render Pass");
723  {
724  pass->SetCommandLabel("Image");
725  pass->SetPipeline(mipmaps_pipeline);
726  pass->SetVertexBuffer(vertex_buffer);
727 
728  VS::FrameInfo frame_info;
729  EXPECT_EQ(pass->GetOrthographicTransform(),
730  Matrix::MakeOrthographic(pass->GetRenderTargetSize()));
731  frame_info.mvp = pass->GetOrthographicTransform() *
732  Matrix::MakeScale(GetContentScale());
733  VS::BindFrameInfo(*pass, host_buffer->EmplaceUniform(frame_info));
734 
735  FS::FragInfo frag_info;
736  frag_info.lod = 0;
737  FS::BindFragInfo(*pass, host_buffer->EmplaceUniform(frag_info));
738 
739  raw_ptr<const Sampler> sampler =
740  context->GetSamplerLibrary()->GetSampler({});
741  auto buffer_view = DeviceBuffer::AsBufferView(device_buffer);
742  auto texture =
743  context->GetResourceAllocator()->CreateTexture(texture_desc);
744  if (!texture->SetContents(device_buffer->OnGetContents(),
745  buffer_view.GetRange().length)) {
746  VALIDATION_LOG << "Could not upload texture to device memory";
747  return false;
748  }
749  FS::BindTex(*pass, texture, sampler);
750 
751  pass->Draw().ok();
752  }
753  pass->EncodeCommands();
754  if (!context->GetCommandQueue()->Submit({buffer}).ok()) {
755  return false;
756  }
757  }
758  host_buffer->Reset();
759  return true;
760  };
761  OpenPlaygroundHere(callback);
762 }
#define VALIDATION_LOG
Definition: validation.h:91

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), impeller::DeviceBuffer::AsBufferView(), buffer_view, impeller::HostBuffer::Create(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::CreateVertexBuffer(), impeller::TextureDescriptor::format, impeller::kCount4, impeller::kHostVisible, impeller::kOpenGLES, impeller::kR8G8B8A8UNormInt, impeller::kRenderTarget, impeller::kShaderRead, impeller::kShaderWrite, impeller::PipelineBuilder< VertexShader_, FragmentShader_ >::MakeDefaultPipelineDescriptor(), impeller::Matrix::MakeOrthographic(), impeller::Matrix::MakeScale(), impeller::TextureDescriptor::mip_count, impeller::VertexBufferBuilder< VertexType_, IndexType_ >::SetLabel(), impeller::DeviceBufferDescriptor::size, impeller::TextureDescriptor::size, impeller::DeviceBufferDescriptor::storage_mode, impeller::TextureDescriptor::storage_mode, impeller::TextureDescriptor::usage, and VALIDATION_LOG.

◆ TEST_P() [447/497]

impeller::testing::TEST_P ( RendererTest  ,
CanBlitTextureToTexture   
)

Definition at line 523 of file renderer_unittests.cc.

523  {
524  if (GetBackend() == PlaygroundBackend::kOpenGLES) {
525  GTEST_SKIP() << "Mipmap test shader not supported on GLES.";
526  }
527  auto context = GetContext();
528  ASSERT_TRUE(context);
529 
530  using VS = MipmapsVertexShader;
531  using FS = MipmapsFragmentShader;
532  auto desc = PipelineBuilder<VS, FS>::MakeDefaultPipelineDescriptor(*context);
533  ASSERT_TRUE(desc.has_value());
534  desc->SetSampleCount(SampleCount::kCount4);
535  desc->SetStencilAttachmentDescriptors(std::nullopt);
536  auto mipmaps_pipeline =
537  context->GetPipelineLibrary()->GetPipeline(std::move(desc)).Get();
538  ASSERT_TRUE(mipmaps_pipeline);
539 
540  TextureDescriptor texture_desc;
541  texture_desc.storage_mode = StorageMode::kHostVisible;
542  texture_desc.format = PixelFormat::kR8G8B8A8UNormInt;
543  texture_desc.size = {800, 600};
544  texture_desc.mip_count = 1u;
545  texture_desc.usage = TextureUsage::kRenderTarget | TextureUsage::kShaderRead;
546  auto texture = context->GetResourceAllocator()->CreateTexture(texture_desc);
547  ASSERT_TRUE(texture);
548 
549  auto bridge = CreateTextureForFixture("bay_bridge.jpg");
550  auto boston = CreateTextureForFixture("boston.jpg");
551  ASSERT_TRUE(bridge && boston);
552  raw_ptr<const Sampler> sampler = context->GetSamplerLibrary()->GetSampler({});
553  ASSERT_TRUE(sampler);
554 
555  // Vertex buffer.
556  VertexBufferBuilder<VS::PerVertexData> vertex_builder;
557  vertex_builder.SetLabel("Box");
558  auto size = Point(boston->GetSize());
559  vertex_builder.AddVertices({
560  {{0, 0}, {0.0, 0.0}}, // 1
561  {{size.x, 0}, {1.0, 0.0}}, // 2
562  {{size.x, size.y}, {1.0, 1.0}}, // 3
563  {{0, 0}, {0.0, 0.0}}, // 1
564  {{size.x, size.y}, {1.0, 1.0}}, // 3
565  {{0, size.y}, {0.0, 1.0}}, // 4
566  });
567  auto vertex_buffer =
568  vertex_builder.CreateVertexBuffer(*context->GetResourceAllocator());
569  ASSERT_TRUE(vertex_buffer);
570 
571  auto host_buffer = HostBuffer::Create(context->GetResourceAllocator(),
572  context->GetIdleWaiter());
573  Playground::RenderCallback callback = [&](RenderTarget& render_target) {
574  auto buffer = context->CreateCommandBuffer();
575  if (!buffer) {
576  return false;
577  }
578  buffer->SetLabel("Playground Command Buffer");
579 
580  {
581  auto pass = buffer->CreateBlitPass();
582  if (!pass) {
583  return false;
584  }
585  pass->SetLabel("Playground Blit Pass");
586 
587  // Blit `bridge` to the top left corner of the texture.
588  pass->AddCopy(bridge, texture);
589 
590  if (!pass->EncodeCommands()) {
591  return false;
592  }
593  }
594 
595  {
596  auto pass = buffer->CreateRenderPass(render_target);
597  if (!pass) {
598  return false;
599  }
600  pass->SetLabel("Playground Render Pass");
601  {
602  pass->SetCommandLabel("Image");
603  pass->SetPipeline(mipmaps_pipeline);
604  pass->SetVertexBuffer(vertex_buffer);
605 
606  VS::FrameInfo frame_info;
607  EXPECT_EQ(pass->GetOrthographicTransform(),
608  Matrix::MakeOrthographic(pass->GetRenderTargetSize()));
609  frame_info.mvp = pass->GetOrthographicTransform() *
610  Matrix::MakeScale(GetContentScale());
611  VS::BindFrameInfo(*pass, host_buffer->EmplaceUniform(frame_info));
612 
613  FS::FragInfo frag_info;
614  frag_info.lod = 0;
615  FS::BindFragInfo(*pass, host_buffer->EmplaceUniform(frag_info));
616 
617  auto sampler = context->GetSamplerLibrary()->GetSampler({});
618  FS::BindTex(*pass, texture, sampler);
619 
620  pass->Draw();
621  }
622  pass->EncodeCommands();
623  }
624 
625  if (!context->GetCommandQueue()->Submit({buffer}).ok()) {
626  return false;
627  }
628  host_buffer->Reset();
629  return true;
630  };
631  OpenPlaygroundHere(callback);
632 }

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() [448/497]

impeller::testing::TEST_P ( RendererTest  ,
CanCreateBoxPrimitive   
)

Definition at line 53 of file renderer_unittests.cc.

53  {
54  using VS = BoxFadeVertexShader;
55  using FS = BoxFadeFragmentShader;
56  auto context = GetContext();
57  ASSERT_TRUE(context);
58  using BoxPipelineBuilder = PipelineBuilder<VS, FS>;
59  auto desc = BoxPipelineBuilder::MakeDefaultPipelineDescriptor(*context);
60  ASSERT_TRUE(desc.has_value());
61  desc->SetSampleCount(SampleCount::kCount4);
62  desc->SetStencilAttachmentDescriptors(std::nullopt);
63 
64  // Vertex buffer.
65  VertexBufferBuilder<VS::PerVertexData> vertex_builder;
66  vertex_builder.SetLabel("Box");
67  vertex_builder.AddVertices({
68  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
69  {{800, 100, 0.0}, {1.0, 0.0}}, // 2
70  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
71  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
72  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
73  {{100, 800, 0.0}, {0.0, 1.0}}, // 4
74  });
75  auto bridge = CreateTextureForFixture("bay_bridge.jpg");
76  auto boston = CreateTextureForFixture("boston.jpg");
77  ASSERT_TRUE(bridge && boston);
78  raw_ptr<const Sampler> sampler = context->GetSamplerLibrary()->GetSampler({});
79  ASSERT_TRUE(sampler);
80 
81  auto host_buffer = HostBuffer::Create(context->GetResourceAllocator(),
82  context->GetIdleWaiter());
83  SinglePassCallback callback = [&](RenderPass& pass) {
84  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
85  static bool wireframe;
86  ImGui::Checkbox("Wireframe", &wireframe);
87  ImGui::End();
88 
89  desc->SetPolygonMode(wireframe ? PolygonMode::kLine : PolygonMode::kFill);
90  auto pipeline = context->GetPipelineLibrary()->GetPipeline(desc).Get();
91 
92  assert(pipeline && pipeline->IsValid());
93 
94  pass.SetCommandLabel("Box");
95  pass.SetPipeline(pipeline);
96  pass.SetVertexBuffer(
97  vertex_builder.CreateVertexBuffer(*context->GetResourceAllocator()));
98 
99  VS::UniformBuffer uniforms;
100  EXPECT_EQ(pass.GetOrthographicTransform(),
101  Matrix::MakeOrthographic(pass.GetRenderTargetSize()));
102  uniforms.mvp =
103  pass.GetOrthographicTransform() * Matrix::MakeScale(GetContentScale());
104  VS::BindUniformBuffer(pass, host_buffer->EmplaceUniform(uniforms));
105 
106  FS::FrameInfo frame_info;
107  frame_info.current_time = GetSecondsElapsed();
108  frame_info.cursor_position = GetCursorPosition();
109  frame_info.window_size.x = GetWindowSize().width;
110  frame_info.window_size.y = GetWindowSize().height;
111 
112  FS::BindFrameInfo(pass, host_buffer->EmplaceUniform(frame_info));
113  FS::BindContents1(pass, boston, sampler);
114  FS::BindContents2(pass, bridge, sampler);
115 
116  host_buffer->Reset();
117  return pass.Draw().ok();
118  };
119  OpenPlaygroundHere(callback);
120 }

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() [449/497]

impeller::testing::TEST_P ( RendererTest  ,
CanGenerateMipmaps   
)

Definition at line 764 of file renderer_unittests.cc.

764  {
765  if (GetBackend() == PlaygroundBackend::kOpenGLES) {
766  GTEST_SKIP() << "Mipmap test shader not supported on GLES.";
767  }
768  auto context = GetContext();
769  ASSERT_TRUE(context);
770 
771  using VS = MipmapsVertexShader;
772  using FS = MipmapsFragmentShader;
773  auto desc = PipelineBuilder<VS, FS>::MakeDefaultPipelineDescriptor(*context);
774  ASSERT_TRUE(desc.has_value());
775  desc->SetSampleCount(SampleCount::kCount4);
776  desc->SetStencilAttachmentDescriptors(std::nullopt);
777  auto mipmaps_pipeline =
778  context->GetPipelineLibrary()->GetPipeline(std::move(desc)).Get();
779  ASSERT_TRUE(mipmaps_pipeline);
780 
781  auto boston = CreateTextureForFixture("boston.jpg", true);
782  ASSERT_TRUE(boston);
783 
784  // Vertex buffer.
785  VertexBufferBuilder<VS::PerVertexData> vertex_builder;
786  vertex_builder.SetLabel("Box");
787  auto size = Point(boston->GetSize());
788  vertex_builder.AddVertices({
789  {{0, 0}, {0.0, 0.0}}, // 1
790  {{size.x, 0}, {1.0, 0.0}}, // 2
791  {{size.x, size.y}, {1.0, 1.0}}, // 3
792  {{0, 0}, {0.0, 0.0}}, // 1
793  {{size.x, size.y}, {1.0, 1.0}}, // 3
794  {{0, size.y}, {0.0, 1.0}}, // 4
795  });
796  auto vertex_buffer =
797  vertex_builder.CreateVertexBuffer(*context->GetResourceAllocator());
798  ASSERT_TRUE(vertex_buffer);
799 
800  bool first_frame = true;
801  auto host_buffer = HostBuffer::Create(context->GetResourceAllocator(),
802  context->GetIdleWaiter());
803  Playground::RenderCallback callback = [&](RenderTarget& render_target) {
804  const char* mip_filter_names[] = {"Base", "Nearest", "Linear"};
805  const MipFilter mip_filters[] = {MipFilter::kBase, MipFilter::kNearest,
806  MipFilter::kLinear};
807  const char* min_filter_names[] = {"Nearest", "Linear"};
808  const MinMagFilter min_filters[] = {MinMagFilter::kNearest,
809  MinMagFilter::kLinear};
810 
811  // UI state.
812  static int selected_mip_filter = 1;
813  static int selected_min_filter = 0;
814  static float lod = 4.5;
815 
816  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
817  ImGui::Combo("Mip filter", &selected_mip_filter, mip_filter_names,
818  sizeof(mip_filter_names) / sizeof(char*));
819  ImGui::Combo("Min filter", &selected_min_filter, min_filter_names,
820  sizeof(min_filter_names) / sizeof(char*));
821  ImGui::SliderFloat("LOD", &lod, 0, boston->GetMipCount() - 1);
822  ImGui::End();
823 
824  auto buffer = context->CreateCommandBuffer();
825  if (!buffer) {
826  return false;
827  }
828  buffer->SetLabel("Playground Command Buffer");
829 
830  if (first_frame) {
831  auto pass = buffer->CreateBlitPass();
832  if (!pass) {
833  return false;
834  }
835  pass->SetLabel("Playground Blit Pass");
836 
837  pass->GenerateMipmap(boston, "Boston Mipmap");
838 
839  pass->EncodeCommands();
840  }
841 
842  first_frame = false;
843 
844  {
845  auto pass = buffer->CreateRenderPass(render_target);
846  if (!pass) {
847  return false;
848  }
849  pass->SetLabel("Playground Render Pass");
850  {
851  pass->SetCommandLabel("Image LOD");
852  pass->SetPipeline(mipmaps_pipeline);
853  pass->SetVertexBuffer(vertex_buffer);
854 
855  VS::FrameInfo frame_info;
856  EXPECT_EQ(pass->GetOrthographicTransform(),
857  Matrix::MakeOrthographic(pass->GetRenderTargetSize()));
858  frame_info.mvp = pass->GetOrthographicTransform() *
859  Matrix::MakeScale(GetContentScale());
860  VS::BindFrameInfo(*pass, host_buffer->EmplaceUniform(frame_info));
861 
862  FS::FragInfo frag_info;
863  frag_info.lod = lod;
864  FS::BindFragInfo(*pass, host_buffer->EmplaceUniform(frag_info));
865 
866  SamplerDescriptor sampler_desc;
867  sampler_desc.mip_filter = mip_filters[selected_mip_filter];
868  sampler_desc.min_filter = min_filters[selected_min_filter];
869  raw_ptr<const Sampler> sampler =
870  context->GetSamplerLibrary()->GetSampler(sampler_desc);
871  FS::BindTex(*pass, boston, sampler);
872 
873  pass->Draw();
874  }
875  pass->EncodeCommands();
876  }
877 
878  if (!context->GetCommandQueue()->Submit({buffer}).ok()) {
879  return false;
880  }
881  host_buffer->Reset();
882  return true;
883  };
884  OpenPlaygroundHere(callback);
885 }
MipFilter
Options for selecting and filtering between mipmap levels.
Definition: formats.h:425
MinMagFilter
Describes how the texture should be sampled when the texture is being shrunk (minified) or expanded (...
Definition: formats.h:415

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), impeller::HostBuffer::Create(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::CreateVertexBuffer(), impeller::kBase, impeller::kCount4, impeller::kLinear, impeller::kNearest, impeller::kOpenGLES, impeller::PipelineBuilder< VertexShader_, FragmentShader_ >::MakeDefaultPipelineDescriptor(), impeller::Matrix::MakeOrthographic(), impeller::Matrix::MakeScale(), impeller::SamplerDescriptor::min_filter, impeller::SamplerDescriptor::mip_filter, and impeller::VertexBufferBuilder< VertexType_, IndexType_ >::SetLabel().

◆ TEST_P() [450/497]

impeller::testing::TEST_P ( RendererTest  ,
CanLookupRenderTargetProperties   
)

Definition at line 1363 of file renderer_unittests.cc.

1363  {
1364  auto context = GetContext();
1365  auto cmd_buffer = context->CreateCommandBuffer();
1366  auto render_target_cache = std::make_shared<RenderTargetAllocator>(
1367  GetContext()->GetResourceAllocator());
1368 
1369  auto render_target = render_target_cache->CreateOffscreen(
1370  *context, {100, 100}, /*mip_count=*/1);
1371  auto render_pass = cmd_buffer->CreateRenderPass(render_target);
1372 
1373  EXPECT_EQ(render_pass->GetSampleCount(), render_target.GetSampleCount());
1374  EXPECT_EQ(render_pass->GetRenderTargetPixelFormat(),
1375  render_target.GetRenderTargetPixelFormat());
1376  EXPECT_EQ(render_pass->HasStencilAttachment(),
1377  render_target.GetStencilAttachment().has_value());
1378  EXPECT_EQ(render_pass->GetRenderTargetSize(),
1379  render_target.GetRenderTargetSize());
1380  render_pass->EncodeCommands();
1381 }

◆ TEST_P() [451/497]

impeller::testing::TEST_P ( RendererTest  ,
CanRenderInstanced   
)

Definition at line 465 of file renderer_unittests.cc.

465  {
466  if (GetParam() == PlaygroundBackend::kOpenGLES) {
467  GTEST_SKIP() << "Instancing is not supported on OpenGL.";
468  }
469  using VS = InstancedDrawVertexShader;
470  using FS = InstancedDrawFragmentShader;
471 
472  VertexBufferBuilder<VS::PerVertexData> builder;
473  builder.AddVertices({
474  VS::PerVertexData{Point{10, 10}},
475  VS::PerVertexData{Point{10, 110}},
476  VS::PerVertexData{Point{110, 10}},
477  VS::PerVertexData{Point{10, 110}},
478  VS::PerVertexData{Point{110, 10}},
479  VS::PerVertexData{Point{110, 110}},
480  });
481 
482  ASSERT_NE(GetContext(), nullptr);
483  auto pipeline =
484  GetContext()
485  ->GetPipelineLibrary()
486  ->GetPipeline(PipelineBuilder<VS, FS>::MakeDefaultPipelineDescriptor(
487  *GetContext())
488  ->SetSampleCount(SampleCount::kCount4)
489  .SetStencilAttachmentDescriptors(std::nullopt))
490 
491  .Get();
492  ASSERT_TRUE(pipeline && pipeline->IsValid());
493 
494  static constexpr size_t kInstancesCount = 5u;
495  VS::InstanceInfo<kInstancesCount> instances;
496  for (size_t i = 0; i < kInstancesCount; i++) {
497  instances.colors[i] = Color::Random();
498  }
499 
500  auto host_buffer = HostBuffer::Create(GetContext()->GetResourceAllocator(),
501  GetContext()->GetIdleWaiter());
502  ASSERT_TRUE(OpenPlaygroundHere([&](RenderPass& pass) -> bool {
503  pass.SetPipeline(pipeline);
504  pass.SetCommandLabel("InstancedDraw");
505 
506  VS::FrameInfo frame_info;
507  EXPECT_EQ(pass.GetOrthographicTransform(),
508  Matrix::MakeOrthographic(pass.GetRenderTargetSize()));
509  frame_info.mvp =
510  pass.GetOrthographicTransform() * Matrix::MakeScale(GetContentScale());
511  VS::BindFrameInfo(pass, host_buffer->EmplaceUniform(frame_info));
512  VS::BindInstanceInfo(pass, host_buffer->EmplaceStorageBuffer(instances));
513  pass.SetVertexBuffer(builder.CreateVertexBuffer(*host_buffer));
514 
515  pass.SetInstanceCount(kInstancesCount);
516  pass.Draw();
517 
518  host_buffer->Reset();
519  return true;
520  }));
521 }

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() [452/497]

impeller::testing::TEST_P ( RendererTest  ,
CanRenderMultiplePrimitives   
)

Definition at line 289 of file renderer_unittests.cc.

289  {
290  using VS = BoxFadeVertexShader;
291  using FS = BoxFadeFragmentShader;
292  auto context = GetContext();
293  ASSERT_TRUE(context);
294  using BoxPipelineBuilder = PipelineBuilder<VS, FS>;
295  auto desc = BoxPipelineBuilder::MakeDefaultPipelineDescriptor(*context);
296  ASSERT_TRUE(desc.has_value());
297  desc->SetSampleCount(SampleCount::kCount4);
298  desc->SetStencilAttachmentDescriptors(std::nullopt);
299  auto box_pipeline =
300  context->GetPipelineLibrary()->GetPipeline(std::move(desc)).Get();
301  ASSERT_TRUE(box_pipeline);
302 
303  // Vertex buffer.
304  VertexBufferBuilder<VS::PerVertexData> vertex_builder;
305  vertex_builder.SetLabel("Box");
306  vertex_builder.AddVertices({
307  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
308  {{800, 100, 0.0}, {1.0, 0.0}}, // 2
309  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
310  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
311  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
312  {{100, 800, 0.0}, {0.0, 1.0}}, // 4
313  });
314  auto vertex_buffer =
315  vertex_builder.CreateVertexBuffer(*context->GetResourceAllocator());
316  ASSERT_TRUE(vertex_buffer);
317 
318  auto bridge = CreateTextureForFixture("bay_bridge.jpg");
319  auto boston = CreateTextureForFixture("boston.jpg");
320  ASSERT_TRUE(bridge && boston);
321  raw_ptr<const Sampler> sampler = context->GetSamplerLibrary()->GetSampler({});
322  ASSERT_TRUE(sampler);
323 
324  auto host_buffer = HostBuffer::Create(context->GetResourceAllocator(),
325  context->GetIdleWaiter());
326  SinglePassCallback callback = [&](RenderPass& pass) {
327  for (size_t i = 0; i < 1; i++) {
328  for (size_t j = 0; j < 1; j++) {
329  pass.SetCommandLabel("Box");
330  pass.SetPipeline(box_pipeline);
331  pass.SetVertexBuffer(vertex_buffer);
332 
333  FS::FrameInfo frame_info;
334  frame_info.current_time = GetSecondsElapsed();
335  frame_info.cursor_position = GetCursorPosition();
336  frame_info.window_size.x = GetWindowSize().width;
337  frame_info.window_size.y = GetWindowSize().height;
338 
339  FS::BindFrameInfo(pass, host_buffer->EmplaceUniform(frame_info));
340  FS::BindContents1(pass, boston, sampler);
341  FS::BindContents2(pass, bridge, sampler);
342 
343  VS::UniformBuffer uniforms;
344  EXPECT_EQ(pass.GetOrthographicTransform(),
345  Matrix::MakeOrthographic(pass.GetRenderTargetSize()));
346  uniforms.mvp = pass.GetOrthographicTransform() *
347  Matrix::MakeScale(GetContentScale()) *
348  Matrix::MakeTranslation({i * 50.0f, j * 50.0f, 0.0f});
349  VS::BindUniformBuffer(pass, host_buffer->EmplaceUniform(uniforms));
350  if (!pass.Draw().ok()) {
351  return false;
352  }
353  }
354  }
355 
356  host_buffer->Reset();
357  return true;
358  };
359  OpenPlaygroundHere(callback);
360 }

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() [453/497]

impeller::testing::TEST_P ( RendererTest  ,
CanRenderPerspectiveCube   
)

Definition at line 177 of file renderer_unittests.cc.

177  {
178  using VS = ColorsVertexShader;
179  using FS = ColorsFragmentShader;
180  auto context = GetContext();
181  ASSERT_TRUE(context);
182  auto desc = PipelineBuilder<VS, FS>::MakeDefaultPipelineDescriptor(*context);
183  ASSERT_TRUE(desc.has_value());
184  desc->SetCullMode(CullMode::kBackFace);
185  desc->SetWindingOrder(WindingOrder::kCounterClockwise);
186  desc->SetSampleCount(SampleCount::kCount4);
187  desc->ClearStencilAttachments();
188 
189  // Setup the vertex layout to take two bindings. The first for positions and
190  // the second for colors.
191  auto vertex_desc = std::make_shared<VertexDescriptor>();
192  ShaderStageIOSlot position_slot = VS::kInputPosition;
193  ShaderStageIOSlot color_slot = VS::kInputColor;
194  position_slot.binding = 0;
195  position_slot.offset = 0;
196  color_slot.binding = 1;
197  color_slot.offset = 0;
198  const std::vector<ShaderStageIOSlot> io_slots = {position_slot, color_slot};
199  const std::vector<ShaderStageBufferLayout> layouts = {
200  ShaderStageBufferLayout{.stride = 12u, .binding = 0},
201  ShaderStageBufferLayout{.stride = 16u, .binding = 1}};
202  vertex_desc->RegisterDescriptorSetLayouts(VS::kDescriptorSetLayouts);
203  vertex_desc->RegisterDescriptorSetLayouts(FS::kDescriptorSetLayouts);
204  vertex_desc->SetStageInputs(io_slots, layouts);
205  desc->SetVertexDescriptor(std::move(vertex_desc));
206  auto pipeline =
207  context->GetPipelineLibrary()->GetPipeline(std::move(desc)).Get();
208  ASSERT_TRUE(pipeline);
209 
210  struct Cube {
211  Vector3 positions[8] = {
212  // -Z
213  {-1, -1, -1},
214  {1, -1, -1},
215  {1, 1, -1},
216  {-1, 1, -1},
217  // +Z
218  {-1, -1, 1},
219  {1, -1, 1},
220  {1, 1, 1},
221  {-1, 1, 1},
222  };
223  Color colors[8] = {
224  Color::Red(), Color::Yellow(), Color::Green(), Color::Blue(),
225  Color::Green(), Color::Blue(), Color::Red(), Color::Yellow(),
226  };
227  uint16_t indices[36] = {
228  1, 5, 2, 2, 5, 6, // +X
229  4, 0, 7, 7, 0, 3, // -X
230  4, 5, 0, 0, 5, 1, // +Y
231  3, 2, 7, 7, 2, 6, // -Y
232  5, 4, 6, 6, 4, 7, // +Z
233  0, 1, 3, 3, 1, 2, // -Z
234  };
235  } cube;
236 
237  auto device_buffer = context->GetResourceAllocator()->CreateBufferWithCopy(
238  reinterpret_cast<uint8_t*>(&cube), sizeof(cube));
239 
240  raw_ptr<const Sampler> sampler = context->GetSamplerLibrary()->GetSampler({});
241  ASSERT_TRUE(sampler);
242 
243  Vector3 euler_angles;
244  auto host_buffer = HostBuffer::Create(context->GetResourceAllocator(),
245  context->GetIdleWaiter());
246  SinglePassCallback callback = [&](RenderPass& pass) {
247  static Degrees fov_y(60);
248  static Scalar distance = 10;
249 
250  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
251  ImGui::SliderFloat("Field of view", &fov_y.degrees, 0, 180);
252  ImGui::SliderFloat("Camera distance", &distance, 0, 30);
253  ImGui::End();
254 
255  pass.SetCommandLabel("Perspective Cube");
256  pass.SetPipeline(pipeline);
257 
258  std::array<BufferView, 2> vertex_buffers = {
259  BufferView(device_buffer,
260  Range(offsetof(Cube, positions), sizeof(Cube::positions))),
261  BufferView(device_buffer,
262  Range(offsetof(Cube, colors), sizeof(Cube::colors))),
263  };
264 
265  BufferView index_buffer(
266  device_buffer, Range(offsetof(Cube, indices), sizeof(Cube::indices)));
267  pass.SetVertexBuffer(vertex_buffers.data(), vertex_buffers.size());
268  pass.SetElementCount(36);
269  pass.SetIndexBuffer(index_buffer, IndexType::k16bit);
270 
271  VS::UniformBuffer uniforms;
272  Scalar time = GetSecondsElapsed();
273  euler_angles = Vector3(0.19 * time, 0.7 * time, 0.43 * time);
274 
275  uniforms.mvp =
276  Matrix::MakePerspective(fov_y, pass.GetRenderTargetSize(), 0, 10) *
277  Matrix::MakeTranslation({0, 0, distance}) *
278  Matrix::MakeRotationX(Radians(euler_angles.x)) *
279  Matrix::MakeRotationY(Radians(euler_angles.y)) *
280  Matrix::MakeRotationZ(Radians(euler_angles.z));
281  VS::BindUniformBuffer(pass, host_buffer->EmplaceUniform(uniforms));
282 
283  host_buffer->Reset();
284  return pass.Draw().ok();
285  };
286  OpenPlaygroundHere(callback);
287 }

References impeller::ShaderStageIOSlot::binding, impeller::Color::Blue(), impeller::HostBuffer::Create(), impeller::Degrees::degrees, impeller::saturated::distance, impeller::Color::Green(), impeller::k16bit, impeller::kBackFace, impeller::kCount4, impeller::kCounterClockwise, impeller::PipelineBuilder< VertexShader_, FragmentShader_ >::MakeDefaultPipelineDescriptor(), impeller::Matrix::MakePerspective(), impeller::Matrix::MakeRotationX(), impeller::Matrix::MakeRotationY(), impeller::Matrix::MakeRotationZ(), impeller::Matrix::MakeTranslation(), impeller::ShaderStageIOSlot::offset, impeller::Color::Red(), impeller::ShaderStageBufferLayout::stride, impeller::Vector3::x, impeller::Vector3::y, impeller::Color::Yellow(), and impeller::Vector3::z.

◆ TEST_P() [454/497]

impeller::testing::TEST_P ( RendererTest  ,
CanRenderToTexture   
)

Definition at line 362 of file renderer_unittests.cc.

362  {
363  using VS = BoxFadeVertexShader;
364  using FS = BoxFadeFragmentShader;
365  auto context = GetContext();
366  ASSERT_TRUE(context);
367  using BoxPipelineBuilder = PipelineBuilder<VS, FS>;
368  auto pipeline_desc =
369  BoxPipelineBuilder::MakeDefaultPipelineDescriptor(*context);
370  pipeline_desc->SetSampleCount(SampleCount::kCount1);
371  pipeline_desc->ClearDepthAttachment();
372  pipeline_desc->SetStencilPixelFormat(PixelFormat::kS8UInt);
373 
374  ASSERT_TRUE(pipeline_desc.has_value());
375  auto box_pipeline =
376  context->GetPipelineLibrary()->GetPipeline(pipeline_desc).Get();
377  ASSERT_TRUE(box_pipeline);
378  auto host_buffer = HostBuffer::Create(context->GetResourceAllocator(),
379  context->GetIdleWaiter());
380 
381  VertexBufferBuilder<VS::PerVertexData> vertex_builder;
382  vertex_builder.SetLabel("Box");
383  vertex_builder.AddVertices({
384  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
385  {{800, 100, 0.0}, {1.0, 0.0}}, // 2
386  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
387  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
388  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
389  {{100, 800, 0.0}, {0.0, 1.0}}, // 4
390  });
391  auto vertex_buffer =
392  vertex_builder.CreateVertexBuffer(*context->GetResourceAllocator());
393  ASSERT_TRUE(vertex_buffer);
394 
395  auto bridge = CreateTextureForFixture("bay_bridge.jpg");
396  auto boston = CreateTextureForFixture("boston.jpg");
397  ASSERT_TRUE(bridge && boston);
398  raw_ptr<const Sampler> sampler = context->GetSamplerLibrary()->GetSampler({});
399  ASSERT_TRUE(sampler);
400 
401  std::shared_ptr<RenderPass> r2t_pass;
402  auto cmd_buffer = context->CreateCommandBuffer();
403  ASSERT_TRUE(cmd_buffer);
404  {
405  ColorAttachment color0;
406  color0.load_action = LoadAction::kClear;
407  color0.store_action = StoreAction::kStore;
408 
409  TextureDescriptor texture_descriptor;
410  ASSERT_NE(pipeline_desc->GetColorAttachmentDescriptor(0u), nullptr);
411  texture_descriptor.format =
412  pipeline_desc->GetColorAttachmentDescriptor(0u)->format;
413  texture_descriptor.storage_mode = StorageMode::kHostVisible;
414  texture_descriptor.size = {400, 400};
415  texture_descriptor.mip_count = 1u;
416  texture_descriptor.usage = TextureUsage::kRenderTarget;
417 
418  color0.texture =
419  context->GetResourceAllocator()->CreateTexture(texture_descriptor);
420 
421  ASSERT_TRUE(color0.IsValid());
422 
423  color0.texture->SetLabel("r2t_target");
424 
425  StencilAttachment stencil0;
426  stencil0.load_action = LoadAction::kClear;
427  stencil0.store_action = StoreAction::kDontCare;
428  TextureDescriptor stencil_texture_desc;
429  stencil_texture_desc.storage_mode = StorageMode::kDeviceTransient;
430  stencil_texture_desc.size = texture_descriptor.size;
431  stencil_texture_desc.format = PixelFormat::kS8UInt;
432  stencil_texture_desc.usage = TextureUsage::kRenderTarget;
433  stencil0.texture =
434  context->GetResourceAllocator()->CreateTexture(stencil_texture_desc);
435 
436  RenderTarget r2t_desc;
437  r2t_desc.SetColorAttachment(color0, 0u);
438  r2t_desc.SetStencilAttachment(stencil0);
439  r2t_pass = cmd_buffer->CreateRenderPass(r2t_desc);
440  ASSERT_TRUE(r2t_pass && r2t_pass->IsValid());
441  }
442 
443  r2t_pass->SetCommandLabel("Box");
444  r2t_pass->SetPipeline(box_pipeline);
445  r2t_pass->SetVertexBuffer(vertex_buffer);
446 
447  FS::FrameInfo frame_info;
448  frame_info.current_time = GetSecondsElapsed();
449  frame_info.cursor_position = GetCursorPosition();
450  frame_info.window_size.x = GetWindowSize().width;
451  frame_info.window_size.y = GetWindowSize().height;
452 
453  FS::BindFrameInfo(*r2t_pass, host_buffer->EmplaceUniform(frame_info));
454  FS::BindContents1(*r2t_pass, boston, sampler);
455  FS::BindContents2(*r2t_pass, bridge, sampler);
456 
457  VS::UniformBuffer uniforms;
458  uniforms.mvp = Matrix::MakeOrthographic(ISize{1024, 768}) *
459  Matrix::MakeTranslation({50.0f, 50.0f, 0.0f});
460  VS::BindUniformBuffer(*r2t_pass, host_buffer->EmplaceUniform(uniforms));
461  ASSERT_TRUE(r2t_pass->Draw().ok());
462  ASSERT_TRUE(r2t_pass->EncodeCommands());
463 }

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() [455/497]

impeller::testing::TEST_P ( RendererTest  ,
CanSepiaToneThenSwizzleWithSubpasses   
)

Definition at line 1505 of file renderer_unittests.cc.

1505  {
1506  // Define shader types
1507  using TextureVS = TextureVertexShader;
1508  using TextureFS = TextureFragmentShader;
1509 
1510  using SwizzleVS = SepiaVertexShader;
1511  using SwizzleFS = SwizzleFragmentShader;
1512 
1513  using SepiaVS = SepiaVertexShader;
1514  using SepiaFS = SepiaFragmentShader;
1515 
1516  auto context = GetContext();
1517  ASSERT_TRUE(context);
1518 
1519  if (!context->GetCapabilities()->SupportsFramebufferFetch()) {
1520  GTEST_SKIP() << "This test uses framebuffer fetch and the backend doesn't "
1521  "support it.";
1522  return;
1523  }
1524 
1525  // Create pipelines.
1526  auto texture_pipeline = CreateDefaultPipeline<TextureVS, TextureFS>(context);
1527  auto swizzle_pipeline = CreateDefaultPipeline<SwizzleVS, SwizzleFS>(context);
1528  auto sepia_pipeline = CreateDefaultPipeline<SepiaVS, SepiaFS>(context);
1529 
1530  ASSERT_TRUE(texture_pipeline);
1531  ASSERT_TRUE(swizzle_pipeline);
1532  ASSERT_TRUE(sepia_pipeline);
1533 
1534  // Vertex buffer builders.
1535  VertexBufferBuilder<TextureVS::PerVertexData> texture_vtx_builder;
1536  texture_vtx_builder.AddVertices({
1537  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
1538  {{800, 100, 0.0}, {1.0, 0.0}}, // 2
1539  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
1540  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
1541  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
1542  {{100, 800, 0.0}, {0.0, 1.0}}, // 4
1543  });
1544 
1545  VertexBufferBuilder<SepiaVS::PerVertexData> sepia_vtx_builder;
1546  sepia_vtx_builder.AddVertices({
1547  {{100, 100, 0.0}}, // 1
1548  {{800, 100, 0.0}}, // 2
1549  {{800, 800, 0.0}}, // 3
1550  {{100, 100, 0.0}}, // 1
1551  {{800, 800, 0.0}}, // 3
1552  {{100, 800, 0.0}}, // 4
1553  });
1554 
1555  auto boston = CreateTextureForFixture("boston.jpg");
1556  ASSERT_TRUE(boston);
1557 
1558  const auto& sampler = context->GetSamplerLibrary()->GetSampler({});
1559  ASSERT_TRUE(sampler);
1560 
1561  SinglePassCallback callback = [&](RenderPass& pass) {
1562  auto buffer = HostBuffer::Create(context->GetResourceAllocator(),
1563  context->GetIdleWaiter());
1564 
1565  // Draw the texture.
1566  {
1567  pass.SetPipeline(texture_pipeline);
1568  pass.SetVertexBuffer(texture_vtx_builder.CreateVertexBuffer(
1569  *context->GetResourceAllocator()));
1570  TextureVS::UniformBuffer uniforms;
1571  uniforms.mvp = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) *
1572  Matrix::MakeScale(GetContentScale());
1573  TextureVS::BindUniformBuffer(pass, buffer->EmplaceUniform(uniforms));
1574  TextureFS::BindTextureContents(pass, boston, sampler);
1575  if (!pass.Draw().ok()) {
1576  return false;
1577  }
1578  }
1579 
1580  // Draw the sepia toner.
1581  {
1582  pass.SetPipeline(sepia_pipeline);
1583  pass.SetVertexBuffer(sepia_vtx_builder.CreateVertexBuffer(
1584  *context->GetResourceAllocator()));
1585  SepiaVS::UniformBuffer uniforms;
1586  uniforms.mvp = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) *
1587  Matrix::MakeScale(GetContentScale());
1588  SepiaVS::BindUniformBuffer(pass, buffer->EmplaceUniform(uniforms));
1589  if (!pass.Draw().ok()) {
1590  return false;
1591  }
1592  }
1593 
1594  // Draw the swizzle.
1595  {
1596  pass.SetPipeline(swizzle_pipeline);
1597  pass.SetVertexBuffer(sepia_vtx_builder.CreateVertexBuffer(
1598  *context->GetResourceAllocator()));
1599  SwizzleVS::UniformBuffer uniforms;
1600  uniforms.mvp = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) *
1601  Matrix::MakeScale(GetContentScale());
1602  SwizzleVS::BindUniformBuffer(pass, buffer->EmplaceUniform(uniforms));
1603  if (!pass.Draw().ok()) {
1604  return false;
1605  }
1606  }
1607 
1608  return true;
1609  };
1610  OpenPlaygroundHere(callback);
1611 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), impeller::HostBuffer::Create(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::CreateVertexBuffer(), impeller::Matrix::MakeOrthographic(), and impeller::Matrix::MakeScale().

◆ TEST_P() [456/497]

impeller::testing::TEST_P ( RendererTest  ,
CanSepiaToneWithSubpasses   
)

Definition at line 1416 of file renderer_unittests.cc.

1416  {
1417  // Define shader types
1418  using TextureVS = TextureVertexShader;
1419  using TextureFS = TextureFragmentShader;
1420 
1421  using SepiaVS = SepiaVertexShader;
1422  using SepiaFS = SepiaFragmentShader;
1423 
1424  auto context = GetContext();
1425  ASSERT_TRUE(context);
1426 
1427  if (!context->GetCapabilities()->SupportsFramebufferFetch()) {
1428  GTEST_SKIP() << "This test uses framebuffer fetch and the backend doesn't "
1429  "support it.";
1430  return;
1431  }
1432 
1433  // Create pipelines.
1434  auto texture_pipeline = CreateDefaultPipeline<TextureVS, TextureFS>(context);
1435  auto sepia_pipeline = CreateDefaultPipeline<SepiaVS, SepiaFS>(context);
1436 
1437  ASSERT_TRUE(texture_pipeline);
1438  ASSERT_TRUE(sepia_pipeline);
1439 
1440  // Vertex buffer builders.
1441  VertexBufferBuilder<TextureVS::PerVertexData> texture_vtx_builder;
1442  texture_vtx_builder.AddVertices({
1443  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
1444  {{800, 100, 0.0}, {1.0, 0.0}}, // 2
1445  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
1446  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
1447  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
1448  {{100, 800, 0.0}, {0.0, 1.0}}, // 4
1449  });
1450 
1451  VertexBufferBuilder<SepiaVS::PerVertexData> sepia_vtx_builder;
1452  sepia_vtx_builder.AddVertices({
1453  {{100, 100, 0.0}}, // 1
1454  {{800, 100, 0.0}}, // 2
1455  {{800, 800, 0.0}}, // 3
1456  {{100, 100, 0.0}}, // 1
1457  {{800, 800, 0.0}}, // 3
1458  {{100, 800, 0.0}}, // 4
1459  });
1460 
1461  auto boston = CreateTextureForFixture("boston.jpg");
1462  ASSERT_TRUE(boston);
1463 
1464  const auto& sampler = context->GetSamplerLibrary()->GetSampler({});
1465  ASSERT_TRUE(sampler);
1466 
1467  SinglePassCallback callback = [&](RenderPass& pass) {
1468  auto buffer = HostBuffer::Create(context->GetResourceAllocator(),
1469  context->GetIdleWaiter());
1470 
1471  // Draw the texture.
1472  {
1473  pass.SetPipeline(texture_pipeline);
1474  pass.SetVertexBuffer(texture_vtx_builder.CreateVertexBuffer(
1475  *context->GetResourceAllocator()));
1476  TextureVS::UniformBuffer uniforms;
1477  uniforms.mvp = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) *
1478  Matrix::MakeScale(GetContentScale());
1479  TextureVS::BindUniformBuffer(pass, buffer->EmplaceUniform(uniforms));
1480  TextureFS::BindTextureContents(pass, boston, sampler);
1481  if (!pass.Draw().ok()) {
1482  return false;
1483  }
1484  }
1485 
1486  // Draw the sepia toner.
1487  {
1488  pass.SetPipeline(sepia_pipeline);
1489  pass.SetVertexBuffer(sepia_vtx_builder.CreateVertexBuffer(
1490  *context->GetResourceAllocator()));
1491  SepiaVS::UniformBuffer uniforms;
1492  uniforms.mvp = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) *
1493  Matrix::MakeScale(GetContentScale());
1494  SepiaVS::BindUniformBuffer(pass, buffer->EmplaceUniform(uniforms));
1495  if (!pass.Draw().ok()) {
1496  return false;
1497  }
1498  }
1499 
1500  return true;
1501  };
1502  OpenPlaygroundHere(callback);
1503 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), impeller::HostBuffer::Create(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::CreateVertexBuffer(), impeller::Matrix::MakeOrthographic(), and impeller::Matrix::MakeScale().

◆ TEST_P() [457/497]

impeller::testing::TEST_P ( RendererTest  ,
DefaultIndexBehavior   
)

Definition at line 1133 of file renderer_unittests.cc.

1133  {
1134  using VS = BoxFadeVertexShader;
1135 
1136  // Do not create any index buffer if no indices were provided.
1137  VertexBufferBuilder<VS::PerVertexData> vertex_builder;
1138  ASSERT_EQ(vertex_builder.GetIndexType(), IndexType::kNone);
1139 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::GetIndexType(), and impeller::kNone.

◆ TEST_P() [458/497]

impeller::testing::TEST_P ( RendererTest  ,
DefaultIndexSize   
)

Definition at line 1123 of file renderer_unittests.cc.

1123  {
1124  using VS = BoxFadeVertexShader;
1125 
1126  // Default to 16bit index buffer size, as this is a reasonable default and
1127  // supported on all backends without extensions.
1128  VertexBufferBuilder<VS::PerVertexData> vertex_builder;
1129  vertex_builder.AppendIndex(0u);
1130  ASSERT_EQ(vertex_builder.GetIndexType(), IndexType::k16bit);
1131 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AppendIndex(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::GetIndexType(), and impeller::k16bit.

◆ TEST_P() [459/497]

impeller::testing::TEST_P ( RendererTest  ,
InactiveUniforms   
)

Definition at line 1075 of file renderer_unittests.cc.

1075  {
1076  using VS = InactiveUniformsVertexShader;
1077  using FS = InactiveUniformsFragmentShader;
1078 
1079  auto context = GetContext();
1080  auto pipeline_descriptor =
1081  PipelineBuilder<VS, FS>::MakeDefaultPipelineDescriptor(*context);
1082  ASSERT_TRUE(pipeline_descriptor.has_value());
1083  pipeline_descriptor->SetSampleCount(SampleCount::kCount4);
1084  pipeline_descriptor->SetStencilAttachmentDescriptors(std::nullopt);
1085  auto pipeline =
1086  context->GetPipelineLibrary()->GetPipeline(pipeline_descriptor).Get();
1087  ASSERT_TRUE(pipeline && pipeline->IsValid());
1088 
1089  auto host_buffer = HostBuffer::Create(context->GetResourceAllocator(),
1090  context->GetIdleWaiter());
1091  SinglePassCallback callback = [&](RenderPass& pass) {
1092  auto size = pass.GetRenderTargetSize();
1093 
1094  pass.SetPipeline(pipeline);
1095  pass.SetCommandLabel("Inactive Uniform");
1096 
1097  VertexBufferBuilder<VS::PerVertexData> builder;
1098  builder.AddVertices({{Point()},
1099  {Point(0, size.height)},
1100  {Point(size.width, 0)},
1101  {Point(size.width, 0)},
1102  {Point(0, size.height)},
1103  {Point(size.width, size.height)}});
1104  pass.SetVertexBuffer(builder.CreateVertexBuffer(*host_buffer));
1105 
1106  VS::FrameInfo frame_info;
1107  EXPECT_EQ(pass.GetOrthographicTransform(), Matrix::MakeOrthographic(size));
1108  frame_info.mvp =
1109  pass.GetOrthographicTransform() * Matrix::MakeScale(GetContentScale());
1110  VS::BindFrameInfo(pass, host_buffer->EmplaceUniform(frame_info));
1111 
1112  FS::FragInfo fs_uniform = {.unused_color = Color::Red(),
1113  .color = Color::Green()};
1114  FS::BindFragInfo(pass, host_buffer->EmplaceUniform(fs_uniform));
1115 
1116  pass.Draw().ok();
1117  host_buffer->Reset();
1118  return true;
1119  };
1120  OpenPlaygroundHere(callback);
1121 }

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() [460/497]

impeller::testing::TEST_P ( RendererTest  ,
Planet   
)

Definition at line 950 of file renderer_unittests.cc.

950  {
951  using VS = PlanetVertexShader;
952  using FS = PlanetFragmentShader;
953 
954  auto context = GetContext();
955  auto pipeline_descriptor =
956  PipelineBuilder<VS, FS>::MakeDefaultPipelineDescriptor(*context);
957  ASSERT_TRUE(pipeline_descriptor.has_value());
958  pipeline_descriptor->SetSampleCount(SampleCount::kCount4);
959  pipeline_descriptor->SetStencilAttachmentDescriptors(std::nullopt);
960  auto pipeline =
961  context->GetPipelineLibrary()->GetPipeline(pipeline_descriptor).Get();
962  ASSERT_TRUE(pipeline && pipeline->IsValid());
963 
964  auto host_buffer = HostBuffer::Create(context->GetResourceAllocator(),
965  context->GetIdleWaiter());
966 
967  SinglePassCallback callback = [&](RenderPass& pass) {
968  static Scalar speed = 0.1;
969  static Scalar planet_size = 550.0;
970  static bool show_normals = false;
971  static bool show_noise = false;
972  static Scalar seed_value = 42.0;
973 
974  auto size = pass.GetRenderTargetSize();
975 
976  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
977  ImGui::SliderFloat("Speed", &speed, 0.0, 10.0);
978  ImGui::SliderFloat("Planet Size", &planet_size, 0.1, 1000);
979  ImGui::Checkbox("Show Normals", &show_normals);
980  ImGui::Checkbox("Show Noise", &show_noise);
981  ImGui::InputFloat("Seed Value", &seed_value);
982  ImGui::End();
983 
984  pass.SetPipeline(pipeline);
985  pass.SetCommandLabel("Planet scene");
986  VertexBufferBuilder<VS::PerVertexData> builder;
987  builder.AddVertices({{Point()},
988  {Point(0, size.height)},
989  {Point(size.width, 0)},
990  {Point(size.width, 0)},
991  {Point(0, size.height)},
992  {Point(size.width, size.height)}});
993  pass.SetVertexBuffer(builder.CreateVertexBuffer(*host_buffer));
994 
995  VS::FrameInfo frame_info;
996  EXPECT_EQ(pass.GetOrthographicTransform(), Matrix::MakeOrthographic(size));
997  frame_info.mvp = pass.GetOrthographicTransform();
998  VS::BindFrameInfo(pass, host_buffer->EmplaceUniform(frame_info));
999 
1000  FS::FragInfo fs_uniform;
1001  fs_uniform.resolution = Point(size);
1002  fs_uniform.time = GetSecondsElapsed();
1003  fs_uniform.speed = speed;
1004  fs_uniform.planet_size = planet_size;
1005  fs_uniform.show_normals = show_normals ? 1.0 : 0.0;
1006  fs_uniform.show_noise = show_noise ? 1.0 : 0.0;
1007  fs_uniform.seed_value = seed_value;
1008  FS::BindFragInfo(pass, host_buffer->EmplaceUniform(fs_uniform));
1009 
1010  pass.Draw().ok();
1011  host_buffer->Reset();
1012  return true;
1013  };
1014  OpenPlaygroundHere(callback);
1015 }

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() [461/497]

impeller::testing::TEST_P ( RendererTest  ,
RenderTargetCreateOffscreenMSAASetsDefaultDepthStencilFormat   
)

Definition at line 1383 of file renderer_unittests.cc.

1384  {
1385  auto context = GetContext();
1386  auto render_target_cache = std::make_shared<RenderTargetAllocator>(
1387  GetContext()->GetResourceAllocator());
1388 
1389  RenderTarget render_target = render_target_cache->CreateOffscreenMSAA(
1390  *context, {100, 100}, /*mip_count=*/1);
1391  EXPECT_EQ(render_target.GetDepthAttachment()
1392  ->texture->GetTextureDescriptor()
1393  .format,
1394  GetContext()->GetCapabilities()->GetDefaultDepthStencilFormat());
1395 }

References impeller::RenderTarget::GetDepthAttachment().

◆ TEST_P() [462/497]

impeller::testing::TEST_P ( RendererTest  ,
StencilMask   
)

Definition at line 1211 of file renderer_unittests.cc.

1211  {
1212  using VS = BoxFadeVertexShader;
1213  using FS = BoxFadeFragmentShader;
1214  auto context = GetContext();
1215  ASSERT_TRUE(context);
1216  using BoxFadePipelineBuilder = PipelineBuilder<VS, FS>;
1217  auto desc = BoxFadePipelineBuilder::MakeDefaultPipelineDescriptor(*context);
1218  ASSERT_TRUE(desc.has_value());
1219 
1220  // Vertex buffer.
1221  VertexBufferBuilder<VS::PerVertexData> vertex_builder;
1222  vertex_builder.SetLabel("Box");
1223  vertex_builder.AddVertices({
1224  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
1225  {{800, 100, 0.0}, {1.0, 0.0}}, // 2
1226  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
1227  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
1228  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
1229  {{100, 800, 0.0}, {0.0, 1.0}}, // 4
1230  });
1231  auto vertex_buffer =
1232  vertex_builder.CreateVertexBuffer(*context->GetResourceAllocator());
1233  ASSERT_TRUE(vertex_buffer);
1234 
1235  desc->SetSampleCount(SampleCount::kCount4);
1236  desc->SetStencilAttachmentDescriptors(std::nullopt);
1237 
1238  auto bridge = CreateTextureForFixture("bay_bridge.jpg");
1239  auto boston = CreateTextureForFixture("boston.jpg");
1240  ASSERT_TRUE(bridge && boston);
1241  raw_ptr<const Sampler> sampler = context->GetSamplerLibrary()->GetSampler({});
1242  ASSERT_TRUE(sampler);
1243 
1244  static bool mirror = false;
1245  static int stencil_reference_write = 0xFF;
1246  static int stencil_reference_read = 0x1;
1247  std::vector<uint8_t> stencil_contents;
1248  static int last_stencil_contents_reference_value = 0;
1249  static int current_front_compare =
1250  CompareFunctionUI().IndexOf(CompareFunction::kLessEqual);
1251  static int current_back_compare =
1252  CompareFunctionUI().IndexOf(CompareFunction::kLessEqual);
1253 
1254  auto host_buffer = HostBuffer::Create(context->GetResourceAllocator(),
1255  context->GetIdleWaiter());
1256  Playground::RenderCallback callback = [&](RenderTarget& render_target) {
1257  auto buffer = context->CreateCommandBuffer();
1258  if (!buffer) {
1259  return false;
1260  }
1261  buffer->SetLabel("Playground Command Buffer");
1262 
1263  {
1264  // Configure the stencil attachment for the test.
1265  RenderTarget::AttachmentConfig stencil_config;
1266  stencil_config.load_action = LoadAction::kLoad;
1267  stencil_config.store_action = StoreAction::kDontCare;
1268  stencil_config.storage_mode = StorageMode::kHostVisible;
1269  render_target.SetupDepthStencilAttachments(
1270  *context, *context->GetResourceAllocator(),
1271  render_target.GetRenderTargetSize(), true, "stencil", stencil_config);
1272  // Fill the stencil buffer with an checkerboard pattern.
1273  const auto target_width = render_target.GetRenderTargetSize().width;
1274  const auto target_height = render_target.GetRenderTargetSize().height;
1275  const size_t target_size = target_width * target_height;
1276  if (stencil_contents.size() != target_size ||
1277  last_stencil_contents_reference_value != stencil_reference_write) {
1278  stencil_contents.resize(target_size);
1279  last_stencil_contents_reference_value = stencil_reference_write;
1280  for (int y = 0; y < target_height; y++) {
1281  for (int x = 0; x < target_width; x++) {
1282  const auto index = y * target_width + x;
1283  const auto kCheckSize = 64;
1284  const auto value =
1285  (((y / kCheckSize) + (x / kCheckSize)) % 2 == 0) *
1286  stencil_reference_write;
1287  stencil_contents[index] = value;
1288  }
1289  }
1290  }
1291  if (!render_target.GetStencilAttachment()->texture->SetContents(
1292  stencil_contents.data(), stencil_contents.size(), 0, false)) {
1293  VALIDATION_LOG << "Could not upload stencil contents to device memory";
1294  return false;
1295  }
1296  auto pass = buffer->CreateRenderPass(render_target);
1297  if (!pass) {
1298  return false;
1299  }
1300  pass->SetLabel("Stencil Buffer");
1301  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
1302  ImGui::SliderInt("Stencil Write Value", &stencil_reference_write, 0,
1303  0xFF);
1304  ImGui::SliderInt("Stencil Compare Value", &stencil_reference_read, 0,
1305  0xFF);
1306  ImGui::Checkbox("Back face mode", &mirror);
1307  ImGui::ListBox("Front face compare function", &current_front_compare,
1308  CompareFunctionUI().labels(), CompareFunctionUI().size());
1309  ImGui::ListBox("Back face compare function", &current_back_compare,
1310  CompareFunctionUI().labels(), CompareFunctionUI().size());
1311  ImGui::End();
1312 
1313  StencilAttachmentDescriptor front;
1314  front.stencil_compare =
1315  CompareFunctionUI().FunctionOf(current_front_compare);
1316  StencilAttachmentDescriptor back;
1317  back.stencil_compare =
1318  CompareFunctionUI().FunctionOf(current_back_compare);
1319  desc->SetStencilAttachmentDescriptors(front, back);
1320  auto pipeline = context->GetPipelineLibrary()->GetPipeline(desc).Get();
1321 
1322  assert(pipeline && pipeline->IsValid());
1323 
1324  pass->SetCommandLabel("Box");
1325  pass->SetPipeline(pipeline);
1326  pass->SetStencilReference(stencil_reference_read);
1327  pass->SetVertexBuffer(vertex_buffer);
1328 
1329  VS::UniformBuffer uniforms;
1330  EXPECT_EQ(pass->GetOrthographicTransform(),
1331  Matrix::MakeOrthographic(pass->GetRenderTargetSize()));
1332  uniforms.mvp = pass->GetOrthographicTransform() *
1333  Matrix::MakeScale(GetContentScale());
1334  if (mirror) {
1335  uniforms.mvp = Matrix::MakeScale(Vector2(-1, 1)) * uniforms.mvp;
1336  }
1337  VS::BindUniformBuffer(*pass, host_buffer->EmplaceUniform(uniforms));
1338 
1339  FS::FrameInfo frame_info;
1340  frame_info.current_time = GetSecondsElapsed();
1341  frame_info.cursor_position = GetCursorPosition();
1342  frame_info.window_size.x = GetWindowSize().width;
1343  frame_info.window_size.y = GetWindowSize().height;
1344 
1345  FS::BindFrameInfo(*pass, host_buffer->EmplaceUniform(frame_info));
1346  FS::BindContents1(*pass, boston, sampler);
1347  FS::BindContents2(*pass, bridge, sampler);
1348  if (!pass->Draw().ok()) {
1349  return false;
1350  }
1351  pass->EncodeCommands();
1352  }
1353 
1354  if (!context->GetCommandQueue()->Submit({buffer}).ok()) {
1355  return false;
1356  }
1357  host_buffer->Reset();
1358  return true;
1359  };
1360  OpenPlaygroundHere(callback);
1361 }
CompareFunction FunctionOf(int index) const
int IndexOf(CompareFunction func) const
static const CompareFunctionUIData & CompareFunctionUI()

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), CompareFunctionUI(), impeller::HostBuffer::Create(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::CreateVertexBuffer(), impeller::testing::CompareFunctionUIData::FunctionOf(), impeller::testing::CompareFunctionUIData::IndexOf(), impeller::kCount4, impeller::kDontCare, impeller::kHostVisible, impeller::kLessEqual, impeller::kLoad, impeller::RenderTarget::AttachmentConfig::load_action, impeller::Matrix::MakeOrthographic(), impeller::Matrix::MakeScale(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::SetLabel(), impeller::StencilAttachmentDescriptor::stencil_compare, impeller::RenderTarget::AttachmentConfig::storage_mode, impeller::RenderTarget::AttachmentConfig::store_action, VALIDATION_LOG, value, and x.

◆ TEST_P() [463/497]

impeller::testing::TEST_P ( RendererTest  ,
TheImpeller   
)

Definition at line 887 of file renderer_unittests.cc.

887  {
888  using VS = ImpellerVertexShader;
889  using FS = ImpellerFragmentShader;
890 
891  auto context = GetContext();
892  auto pipeline_descriptor =
893  PipelineBuilder<VS, FS>::MakeDefaultPipelineDescriptor(*context);
894  ASSERT_TRUE(pipeline_descriptor.has_value());
895  pipeline_descriptor->SetSampleCount(SampleCount::kCount4);
896  pipeline_descriptor->SetStencilAttachmentDescriptors(std::nullopt);
897  auto pipeline =
898  context->GetPipelineLibrary()->GetPipeline(pipeline_descriptor).Get();
899  ASSERT_TRUE(pipeline && pipeline->IsValid());
900 
901  auto blue_noise = CreateTextureForFixture("blue_noise.png");
902  SamplerDescriptor noise_sampler_desc;
903  noise_sampler_desc.width_address_mode = SamplerAddressMode::kRepeat;
904  noise_sampler_desc.height_address_mode = SamplerAddressMode::kRepeat;
905  raw_ptr<const Sampler> noise_sampler =
906  context->GetSamplerLibrary()->GetSampler(noise_sampler_desc);
907 
908  auto cube_map = CreateTextureCubeForFixture(
909  {"table_mountain_px.png", "table_mountain_nx.png",
910  "table_mountain_py.png", "table_mountain_ny.png",
911  "table_mountain_pz.png", "table_mountain_nz.png"});
912  raw_ptr<const Sampler> cube_map_sampler =
913  context->GetSamplerLibrary()->GetSampler({});
914  auto host_buffer = HostBuffer::Create(context->GetResourceAllocator(),
915  context->GetIdleWaiter());
916 
917  SinglePassCallback callback = [&](RenderPass& pass) {
918  auto size = pass.GetRenderTargetSize();
919 
920  pass.SetPipeline(pipeline);
921  pass.SetCommandLabel("Impeller SDF scene");
922  VertexBufferBuilder<VS::PerVertexData> builder;
923  builder.AddVertices({{Point()},
924  {Point(0, size.height)},
925  {Point(size.width, 0)},
926  {Point(size.width, 0)},
927  {Point(0, size.height)},
928  {Point(size.width, size.height)}});
929  pass.SetVertexBuffer(builder.CreateVertexBuffer(*host_buffer));
930 
931  VS::FrameInfo frame_info;
932  EXPECT_EQ(pass.GetOrthographicTransform(), Matrix::MakeOrthographic(size));
933  frame_info.mvp = pass.GetOrthographicTransform();
934  VS::BindFrameInfo(pass, host_buffer->EmplaceUniform(frame_info));
935 
936  FS::FragInfo fs_uniform;
937  fs_uniform.texture_size = Point(size);
938  fs_uniform.time = GetSecondsElapsed();
939  FS::BindFragInfo(pass, host_buffer->EmplaceUniform(fs_uniform));
940  FS::BindBlueNoise(pass, blue_noise, noise_sampler);
941  FS::BindCubeMap(pass, cube_map, cube_map_sampler);
942 
943  pass.Draw().ok();
944  host_buffer->Reset();
945  return true;
946  };
947  OpenPlaygroundHere(callback);
948 }

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() [464/497]

impeller::testing::TEST_P ( RendererTest  ,
VertexBufferBuilder   
)

Definition at line 1141 of file renderer_unittests.cc.

1141  {
1142  // Does not create index buffer if one is provided.
1143  using VS = BoxFadeVertexShader;
1144  VertexBufferBuilder<VS::PerVertexData> vertex_builder;
1145  vertex_builder.SetLabel("Box");
1146  vertex_builder.AddVertices({
1147  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
1148  {{800, 100, 0.0}, {1.0, 0.0}}, // 2
1149  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
1150  {{100, 800, 0.0}, {0.0, 1.0}}, // 4
1151  });
1152  vertex_builder.AppendIndex(0);
1153  vertex_builder.AppendIndex(1);
1154  vertex_builder.AppendIndex(2);
1155  vertex_builder.AppendIndex(1);
1156  vertex_builder.AppendIndex(2);
1157  vertex_builder.AppendIndex(3);
1158 
1159  ASSERT_EQ(vertex_builder.GetIndexCount(), 6u);
1160  ASSERT_EQ(vertex_builder.GetVertexCount(), 4u);
1161 }

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() [465/497]

impeller::testing::TEST_P ( RenderTargetCacheTest  ,
CachedTextureGetsNewAttachmentConfig   
)

Definition at line 122 of file render_target_cache_unittests.cc.

122  {
123  auto render_target_cache = RenderTargetCache(
124  GetContext()->GetResourceAllocator(), /*keep_alive_frame_count=*/0);
125 
126  render_target_cache.Start();
127  RenderTarget::AttachmentConfig color_attachment_config =
128  RenderTarget::kDefaultColorAttachmentConfig;
129  RenderTarget target1 = render_target_cache.CreateOffscreen(
130  *GetContext(), {100, 100}, 1, "Offscreen1", color_attachment_config);
131  render_target_cache.End();
132 
133  render_target_cache.Start();
134  color_attachment_config.clear_color = Color::Red();
135  RenderTarget target2 = render_target_cache.CreateOffscreen(
136  *GetContext(), {100, 100}, 1, "Offscreen2", color_attachment_config);
137  render_target_cache.End();
138 
139  ColorAttachment color1 = target1.GetColorAttachment(0);
140  ColorAttachment color2 = target2.GetColorAttachment(0);
141  // The second color attachment should reuse the first attachment's texture
142  // but with attributes from the second AttachmentConfig.
143  EXPECT_EQ(color2.texture, color1.texture);
144  EXPECT_EQ(color2.clear_color, Color::Red());
145 }

References impeller::ColorAttachment::clear_color, impeller::RenderTarget::AttachmentConfig::clear_color, impeller::RenderTarget::GetColorAttachment(), impeller::RenderTarget::kDefaultColorAttachmentConfig, impeller::Color::Red(), and impeller::Attachment::texture.

◆ TEST_P() [466/497]

impeller::testing::TEST_P ( RenderTargetCacheTest  ,
CachesUsedTexturesAcrossFrames   
)

Definition at line 52 of file render_target_cache_unittests.cc.

52  {
53  auto render_target_cache = RenderTargetCache(
54  GetContext()->GetResourceAllocator(), /*keep_alive_frame_count=*/0);
55 
56  render_target_cache.Start();
57  // Create two render targets of the same exact size/shape. Both should be
58  // marked as used this frame, so the cached data set will contain two.
59  render_target_cache.CreateOffscreen(*GetContext(), {100, 100}, 1);
60  render_target_cache.CreateOffscreen(*GetContext(), {100, 100}, 1);
61 
62  EXPECT_EQ(render_target_cache.CachedTextureCount(), 2u);
63 
64  render_target_cache.End();
65  render_target_cache.Start();
66 
67  // Next frame, only create one texture. The set will still contain two,
68  // but one will be removed at the end of the frame.
69  render_target_cache.CreateOffscreen(*GetContext(), {100, 100}, 1);
70  EXPECT_EQ(render_target_cache.CachedTextureCount(), 2u);
71 
72  render_target_cache.End();
73  EXPECT_EQ(render_target_cache.CachedTextureCount(), 1u);
74 }

◆ TEST_P() [467/497]

impeller::testing::TEST_P ( RenderTargetCacheTest  ,
CachesUsedTexturesAcrossFramesWithKeepAlive   
)

Definition at line 76 of file render_target_cache_unittests.cc.

76  {
77  auto render_target_cache = RenderTargetCache(
78  GetContext()->GetResourceAllocator(), /*keep_alive_frame_count=*/3);
79 
80  render_target_cache.Start();
81  // Create two render targets of the same exact size/shape. Both should be
82  // marked as used this frame, so the cached data set will contain two.
83  render_target_cache.CreateOffscreen(*GetContext(), {100, 100}, 1);
84  render_target_cache.CreateOffscreen(*GetContext(), {100, 100}, 1);
85 
86  EXPECT_EQ(render_target_cache.CachedTextureCount(), 2u);
87 
88  render_target_cache.End();
89  render_target_cache.Start();
90 
91  // The unused texture is kept alive until the keep alive countdown
92  // reaches 0.
93  EXPECT_EQ(render_target_cache.CachedTextureCount(), 2u);
94 
95  for (auto i = 0; i < 3; i++) {
96  render_target_cache.Start();
97  render_target_cache.End();
98  EXPECT_EQ(render_target_cache.CachedTextureCount(), 2u);
99  }
100  // After the countdown has elapsed the texture is removed.
101  render_target_cache.Start();
102  render_target_cache.End();
103  EXPECT_EQ(render_target_cache.CachedTextureCount(), 0u);
104 }

◆ TEST_P() [468/497]

impeller::testing::TEST_P ( RenderTargetCacheTest  ,
CreateWithEmptySize   
)

Definition at line 147 of file render_target_cache_unittests.cc.

147  {
148  auto render_target_cache = RenderTargetCache(
149  GetContext()->GetResourceAllocator(), /*keep_alive_frame_count=*/0);
150 
151  render_target_cache.Start();
152  RenderTarget empty_target =
153  render_target_cache.CreateOffscreen(*GetContext(), {100, 0}, 1);
154  RenderTarget empty_target_msaa =
155  render_target_cache.CreateOffscreenMSAA(*GetContext(), {0, 0}, 1);
156  render_target_cache.End();
157 
158  {
159  ScopedValidationDisable disable_validation;
160  EXPECT_FALSE(empty_target.IsValid());
161  EXPECT_FALSE(empty_target_msaa.IsValid());
162  }
163 }

References impeller::RenderTarget::IsValid().

◆ TEST_P() [469/497]

impeller::testing::TEST_P ( RenderTargetCacheTest  ,
DoesNotPersistFailedAllocations   
)

Definition at line 106 of file render_target_cache_unittests.cc.

106  {
107  ScopedValidationDisable disable;
108  auto allocator = std::make_shared<TestAllocator>();
109  auto render_target_cache =
110  RenderTargetCache(allocator, /*keep_alive_frame_count=*/0);
111 
112  render_target_cache.Start();
113  allocator->should_fail = true;
114 
115  auto render_target =
116  render_target_cache.CreateOffscreen(*GetContext(), {100, 100}, 1);
117 
118  EXPECT_FALSE(render_target.IsValid());
119  EXPECT_EQ(render_target_cache.CachedTextureCount(), 0u);
120 }

◆ TEST_P() [470/497]

impeller::testing::TEST_P ( RuntimeStageTest  ,
CanCreatePipelineFromRuntimeStage   
)

Definition at line 315 of file runtime_stage_unittests.cc.

315  {
316  auto stages = OpenAssetAsRuntimeStage("ink_sparkle.frag.iplr");
317  auto stage = stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
318 
319  ASSERT_TRUE(stage);
320  ASSERT_NE(stage, nullptr);
321  ASSERT_TRUE(RegisterStage(*stage));
322  auto library = GetContext()->GetShaderLibrary();
323  using VS = RuntimeEffectVertexShader;
324  PipelineDescriptor desc;
325  desc.SetLabel("Runtime Stage InkSparkle");
326  desc.AddStageEntrypoint(
327  library->GetFunction(VS::kEntrypointName, ShaderStage::kVertex));
328  desc.AddStageEntrypoint(
329  library->GetFunction(stage->GetEntrypoint(), ShaderStage::kFragment));
330  auto vertex_descriptor = std::make_shared<VertexDescriptor>();
331  vertex_descriptor->SetStageInputs(VS::kAllShaderStageInputs,
332  VS::kInterleavedBufferLayout);
333 
334  std::array<DescriptorSetLayout, 2> descriptor_set_layouts = {
335  VS::kDescriptorSetLayouts[0],
336  DescriptorSetLayout{
337  .binding = 64u,
338  .descriptor_type = DescriptorType::kUniformBuffer,
339  .shader_stage = ShaderStage::kFragment,
340  },
341  };
342  vertex_descriptor->RegisterDescriptorSetLayouts(descriptor_set_layouts);
343 
344  desc.SetVertexDescriptor(std::move(vertex_descriptor));
345  ColorAttachmentDescriptor color0;
346  color0.format = GetContext()->GetCapabilities()->GetDefaultColorFormat();
347  StencilAttachmentDescriptor stencil0;
348  stencil0.stencil_compare = CompareFunction::kEqual;
349  desc.SetColorAttachmentDescriptor(0u, color0);
350  desc.SetStencilAttachmentDescriptors(stencil0);
351  const auto stencil_fmt =
352  GetContext()->GetCapabilities()->GetDefaultStencilFormat();
353  desc.SetStencilPixelFormat(stencil_fmt);
354  auto pipeline = GetContext()->GetPipelineLibrary()->GetPipeline(desc).Get();
355  ASSERT_NE(pipeline, nullptr);
356 }

References impeller::PipelineDescriptor::AddStageEntrypoint(), impeller::DescriptorSetLayout::binding, impeller::ColorAttachmentDescriptor::format, impeller::kEqual, impeller::kFragment, impeller::kUniformBuffer, impeller::kVertex, impeller::PlaygroundBackendToRuntimeStageBackend(), impeller::PipelineDescriptor::SetColorAttachmentDescriptor(), impeller::PipelineDescriptor::SetLabel(), impeller::PipelineDescriptor::SetStencilAttachmentDescriptors(), impeller::PipelineDescriptor::SetStencilPixelFormat(), impeller::PipelineDescriptor::SetVertexDescriptor(), and impeller::StencilAttachmentDescriptor::stencil_compare.

◆ TEST_P() [471/497]

impeller::testing::TEST_P ( RuntimeStageTest  ,
CanReadUniforms   
)

Definition at line 56 of file runtime_stage_unittests.cc.

56  {
57  const std::shared_ptr<fml::Mapping> fixture =
58  flutter::testing::OpenFixtureAsMapping("ink_sparkle.frag.iplr");
59  ASSERT_TRUE(fixture);
60  ASSERT_GT(fixture->GetSize(), 0u);
61  auto stages = RuntimeStage::DecodeRuntimeStages(fixture);
62  auto stage = stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
63 
64  ASSERT_TRUE(stage->IsValid());
65  switch (GetBackend()) {
66  case PlaygroundBackend::kMetal:
67  [[fallthrough]];
68  case PlaygroundBackend::kOpenGLES: {
69  ASSERT_EQ(stage->GetUniforms().size(), 17u);
70  {
71  auto uni = stage->GetUniform("u_color");
72  ASSERT_NE(uni, nullptr);
73  EXPECT_EQ(uni->dimensions.rows, 4u);
74  EXPECT_EQ(uni->dimensions.cols, 1u);
75  EXPECT_EQ(uni->location, 0u);
76  EXPECT_EQ(uni->type, RuntimeUniformType::kFloat);
77  }
78  {
79  auto uni = stage->GetUniform("u_alpha");
80  ASSERT_NE(uni, nullptr);
81  EXPECT_EQ(uni->dimensions.rows, 1u);
82  EXPECT_EQ(uni->dimensions.cols, 1u);
83  EXPECT_EQ(uni->location, 1u);
84  EXPECT_EQ(uni->type, RuntimeUniformType::kFloat);
85  }
86  {
87  auto uni = stage->GetUniform("u_sparkle_color");
88  ASSERT_NE(uni, nullptr);
89  EXPECT_EQ(uni->dimensions.rows, 4u);
90  EXPECT_EQ(uni->dimensions.cols, 1u);
91  EXPECT_EQ(uni->location, 2u);
92  EXPECT_EQ(uni->type, RuntimeUniformType::kFloat);
93  }
94  {
95  auto uni = stage->GetUniform("u_sparkle_alpha");
96  ASSERT_NE(uni, nullptr);
97  EXPECT_EQ(uni->dimensions.rows, 1u);
98  EXPECT_EQ(uni->dimensions.cols, 1u);
99  EXPECT_EQ(uni->location, 3u);
100  EXPECT_EQ(uni->type, RuntimeUniformType::kFloat);
101  }
102  {
103  auto uni = stage->GetUniform("u_blur");
104  ASSERT_NE(uni, nullptr);
105  EXPECT_EQ(uni->dimensions.rows, 1u);
106  EXPECT_EQ(uni->dimensions.cols, 1u);
107  EXPECT_EQ(uni->location, 4u);
108  EXPECT_EQ(uni->type, RuntimeUniformType::kFloat);
109  }
110  {
111  auto uni = stage->GetUniform("u_radius_scale");
112  ASSERT_NE(uni, nullptr);
113  EXPECT_EQ(uni->dimensions.rows, 1u);
114  EXPECT_EQ(uni->dimensions.cols, 1u);
115  EXPECT_EQ(uni->location, 6u);
116  EXPECT_EQ(uni->type, RuntimeUniformType::kFloat);
117  }
118  {
119  auto uni = stage->GetUniform("u_max_radius");
120  ASSERT_NE(uni, nullptr);
121  EXPECT_EQ(uni->dimensions.rows, 1u);
122  EXPECT_EQ(uni->dimensions.cols, 1u);
123  EXPECT_EQ(uni->location, 7u);
124  EXPECT_EQ(uni->type, RuntimeUniformType::kFloat);
125  }
126  {
127  auto uni = stage->GetUniform("u_resolution_scale");
128  ASSERT_NE(uni, nullptr);
129  EXPECT_EQ(uni->dimensions.rows, 2u);
130  EXPECT_EQ(uni->dimensions.cols, 1u);
131  EXPECT_EQ(uni->location, 8u);
132  EXPECT_EQ(uni->type, RuntimeUniformType::kFloat);
133  }
134  {
135  auto uni = stage->GetUniform("u_noise_scale");
136  ASSERT_NE(uni, nullptr);
137  EXPECT_EQ(uni->dimensions.rows, 2u);
138  EXPECT_EQ(uni->dimensions.cols, 1u);
139  EXPECT_EQ(uni->location, 9u);
140  EXPECT_EQ(uni->type, RuntimeUniformType::kFloat);
141  }
142  {
143  auto uni = stage->GetUniform("u_noise_phase");
144  ASSERT_NE(uni, nullptr);
145  EXPECT_EQ(uni->dimensions.rows, 1u);
146  EXPECT_EQ(uni->dimensions.cols, 1u);
147  EXPECT_EQ(uni->location, 10u);
148  EXPECT_EQ(uni->type, RuntimeUniformType::kFloat);
149  }
150 
151  {
152  auto uni = stage->GetUniform("u_circle1");
153  ASSERT_NE(uni, nullptr);
154  EXPECT_EQ(uni->dimensions.rows, 2u);
155  EXPECT_EQ(uni->dimensions.cols, 1u);
156  EXPECT_EQ(uni->location, 11u);
157  EXPECT_EQ(uni->type, RuntimeUniformType::kFloat);
158  }
159  {
160  auto uni = stage->GetUniform("u_circle2");
161  ASSERT_NE(uni, nullptr);
162  EXPECT_EQ(uni->dimensions.rows, 2u);
163  EXPECT_EQ(uni->dimensions.cols, 1u);
164  EXPECT_EQ(uni->location, 12u);
165  EXPECT_EQ(uni->type, RuntimeUniformType::kFloat);
166  }
167  {
168  auto uni = stage->GetUniform("u_circle3");
169  ASSERT_NE(uni, nullptr);
170  EXPECT_EQ(uni->dimensions.rows, 2u);
171  EXPECT_EQ(uni->dimensions.cols, 1u);
172  EXPECT_EQ(uni->location, 13u);
173  EXPECT_EQ(uni->type, RuntimeUniformType::kFloat);
174  }
175  {
176  auto uni = stage->GetUniform("u_rotation1");
177  ASSERT_NE(uni, nullptr);
178  EXPECT_EQ(uni->dimensions.rows, 2u);
179  EXPECT_EQ(uni->dimensions.cols, 1u);
180  EXPECT_EQ(uni->location, 14u);
181  EXPECT_EQ(uni->type, RuntimeUniformType::kFloat);
182  }
183  {
184  auto uni = stage->GetUniform("u_rotation2");
185  ASSERT_NE(uni, nullptr);
186  EXPECT_EQ(uni->dimensions.rows, 2u);
187  EXPECT_EQ(uni->dimensions.cols, 1u);
188  EXPECT_EQ(uni->location, 15u);
189  EXPECT_EQ(uni->type, RuntimeUniformType::kFloat);
190  }
191  {
192  auto uni = stage->GetUniform("u_rotation3");
193  ASSERT_NE(uni, nullptr);
194  EXPECT_EQ(uni->dimensions.rows, 2u);
195  EXPECT_EQ(uni->dimensions.cols, 1u);
196  EXPECT_EQ(uni->location, 16u);
197  EXPECT_EQ(uni->type, RuntimeUniformType::kFloat);
198  }
199  break;
200  }
201  case PlaygroundBackend::kVulkan: {
202  EXPECT_EQ(stage->GetUniforms().size(), 1u);
203  auto uni = stage->GetUniform(RuntimeStage::kVulkanUBOName);
204  ASSERT_TRUE(uni);
205  EXPECT_EQ(uni->type, RuntimeUniformType::kStruct);
206  EXPECT_EQ(uni->struct_float_count, 32u);
207 
208  // There are 36 4 byte chunks in the UBO: 32 for the 32 floats, and 4 for
209  // padding. Initialize a vector as if they'll all be floats, then manually
210  // set the few padding bytes. If the shader changes, the padding locations
211  // will change as well. For example, if `u_alpha` was moved to the end,
212  // three bytes of padding could potentially be dropped - or if some of the
213  // scalar floats were changed to vec2 or vec4s, or if any vec3s are
214  // introduced.
215  // This means 36 * 4 = 144 bytes total.
216 
217  EXPECT_EQ(uni->GetSize(), 144u);
218  std::vector<uint8_t> layout(uni->GetSize() / sizeof(float), 1);
219  layout[5] = 0;
220  layout[6] = 0;
221  layout[7] = 0;
222  layout[23] = 0;
223 
224  EXPECT_THAT(uni->struct_layout, ::testing::ElementsAreArray(layout));
225  break;
226  }
227  }
228 }

References impeller::RuntimeStage::DecodeRuntimeStages(), impeller::kFloat, impeller::kMetal, impeller::kOpenGLES, impeller::kStruct, impeller::kVulkan, impeller::RuntimeStage::kVulkanUBOName, and impeller::PlaygroundBackendToRuntimeStageBackend().

◆ TEST_P() [472/497]

impeller::testing::TEST_P ( RuntimeStageTest  ,
CanReadUniformsSamplerAfterUBO   
)

Definition at line 255 of file runtime_stage_unittests.cc.

255  {
256  if (GetBackend() != PlaygroundBackend::kVulkan) {
257  GTEST_SKIP() << "Test only relevant for Vulkan";
258  }
259  const std::shared_ptr<fml::Mapping> fixture =
260  flutter::testing::OpenFixtureAsMapping(
261  "uniforms_and_sampler_2.frag.iplr");
262  ASSERT_TRUE(fixture);
263  ASSERT_GT(fixture->GetSize(), 0u);
264  auto stages = RuntimeStage::DecodeRuntimeStages(fixture);
265  auto stage = stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
266 
267  EXPECT_EQ(stage->GetUniforms().size(), 2u);
268  auto uni = stage->GetUniform(RuntimeStage::kVulkanUBOName);
269  ASSERT_TRUE(uni);
270  // Struct must be offset at 45.
271  EXPECT_EQ(uni->type, RuntimeUniformType::kStruct);
272  EXPECT_EQ(uni->binding, 64u);
273  // Sampler should be offset at 64 but due to current bug
274  // has offset of 0, the correct offset is computed at runtime.
275  auto sampler_uniform = stage->GetUniform("u_texture");
276  EXPECT_EQ(sampler_uniform->type, RuntimeUniformType::kSampledImage);
277  EXPECT_EQ(sampler_uniform->binding, 65u);
278 }

References impeller::RuntimeStage::DecodeRuntimeStages(), impeller::kSampledImage, impeller::kStruct, impeller::kVulkan, impeller::RuntimeStage::kVulkanUBOName, and impeller::PlaygroundBackendToRuntimeStageBackend().

◆ TEST_P() [473/497]

impeller::testing::TEST_P ( RuntimeStageTest  ,
CanReadUniformsSamplerBeforeUBO   
)

Definition at line 230 of file runtime_stage_unittests.cc.

230  {
231  if (GetBackend() != PlaygroundBackend::kVulkan) {
232  GTEST_SKIP() << "Test only relevant for Vulkan";
233  }
234  const std::shared_ptr<fml::Mapping> fixture =
235  flutter::testing::OpenFixtureAsMapping(
236  "uniforms_and_sampler_1.frag.iplr");
237  ASSERT_TRUE(fixture);
238  ASSERT_GT(fixture->GetSize(), 0u);
239  auto stages = RuntimeStage::DecodeRuntimeStages(fixture);
240  auto stage = stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
241 
242  EXPECT_EQ(stage->GetUniforms().size(), 2u);
243  auto uni = stage->GetUniform(RuntimeStage::kVulkanUBOName);
244  ASSERT_TRUE(uni);
245  // Struct must be offset at 65.
246  EXPECT_EQ(uni->type, RuntimeUniformType::kStruct);
247  EXPECT_EQ(uni->binding, 65u);
248  // Sampler should be offset at 64 but due to current bug
249  // has offset of 0, the correct offset is computed at runtime.
250  auto sampler_uniform = stage->GetUniform("u_texture");
251  EXPECT_EQ(sampler_uniform->type, RuntimeUniformType::kSampledImage);
252  EXPECT_EQ(sampler_uniform->binding, 64u);
253 }

References impeller::RuntimeStage::DecodeRuntimeStages(), impeller::kSampledImage, impeller::kStruct, impeller::kVulkan, impeller::RuntimeStage::kVulkanUBOName, and impeller::PlaygroundBackendToRuntimeStageBackend().

◆ TEST_P() [474/497]

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() [475/497]

impeller::testing::TEST_P ( RuntimeStageTest  ,
CanRegisterStage   
)

Definition at line 280 of file runtime_stage_unittests.cc.

280  {
281  const std::shared_ptr<fml::Mapping> fixture =
282  flutter::testing::OpenFixtureAsMapping("ink_sparkle.frag.iplr");
283  ASSERT_TRUE(fixture);
284  ASSERT_GT(fixture->GetSize(), 0u);
285  auto stages = RuntimeStage::DecodeRuntimeStages(fixture);
286  auto stage = stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
287  ASSERT_TRUE(stage->IsValid());
288  std::promise<bool> registration;
289  auto future = registration.get_future();
290  auto library = GetContext()->GetShaderLibrary();
291  library->RegisterFunction(
292  stage->GetEntrypoint(), //
293  ToShaderStage(stage->GetShaderStage()), //
294  stage->GetCodeMapping(), //
295  fml::MakeCopyable([reg = std::move(registration)](bool result) mutable {
296  reg.set_value(result);
297  }));
298  ASSERT_TRUE(future.get());
299  {
300  auto function =
301  library->GetFunction(stage->GetEntrypoint(), ShaderStage::kFragment);
302  ASSERT_NE(function, nullptr);
303  }
304 
305  // Check if unregistering works.
306 
307  library->UnregisterFunction(stage->GetEntrypoint(), ShaderStage::kFragment);
308  {
309  auto function =
310  library->GetFunction(stage->GetEntrypoint(), ShaderStage::kFragment);
311  ASSERT_EQ(function, nullptr);
312  }
313 }
constexpr ShaderStage ToShaderStage(RuntimeShaderStage stage)
Definition: shader_types.h:29

References impeller::RuntimeStage::DecodeRuntimeStages(), impeller::kFragment, impeller::PlaygroundBackendToRuntimeStageBackend(), and impeller::ToShaderStage().

◆ TEST_P() [476/497]

impeller::testing::TEST_P ( RuntimeStageTest  ,
CanRejectInvalidBlob   
)

Definition at line 40 of file runtime_stage_unittests.cc.

40  {
41  ScopedValidationDisable disable_validation;
42  const std::shared_ptr<fml::Mapping> fixture =
43  flutter::testing::OpenFixtureAsMapping("ink_sparkle.frag.iplr");
44  ASSERT_TRUE(fixture);
45  auto junk_allocation = std::make_shared<Allocation>();
46  ASSERT_TRUE(junk_allocation->Truncate(Bytes{fixture->GetSize()}, false));
47  // Not meant to be secure. Just reject obviously bad blobs using magic
48  // numbers.
49  ::memset(junk_allocation->GetBuffer(), 127,
50  junk_allocation->GetLength().GetByteSize());
51  auto stages = RuntimeStage::DecodeRuntimeStages(
52  CreateMappingFromAllocation(junk_allocation));
53  ASSERT_FALSE(stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())]);
54 }
std::shared_ptr< fml::Mapping > CreateMappingFromAllocation(const std::shared_ptr< Allocation > &allocation)
Creates a mapping from allocation.
Definition: allocation.cc:99

References impeller::CreateMappingFromAllocation(), impeller::RuntimeStage::DecodeRuntimeStages(), and impeller::PlaygroundBackendToRuntimeStageBackend().

◆ TEST_P() [477/497]

impeller::testing::TEST_P ( RuntimeStageTest  ,
ContainsExpectedShaderTypes   
)

Definition at line 358 of file runtime_stage_unittests.cc.

358  {
359  auto stages = OpenAssetAsRuntimeStage("ink_sparkle.frag.iplr");
360  // Right now, SkSL gets implicitly bundled regardless of what the build rule
361  // for this test requested. After
362  // https://github.com/flutter/flutter/issues/138919, this may require a build
363  // rule change or a new test.
364  EXPECT_TRUE(stages[RuntimeStageBackend::kSkSL]);
365 
366  EXPECT_TRUE(stages[RuntimeStageBackend::kOpenGLES]);
367  EXPECT_TRUE(stages[RuntimeStageBackend::kMetal]);
368  EXPECT_TRUE(stages[RuntimeStageBackend::kVulkan]);
369 }

References impeller::kMetal, impeller::kOpenGLES, impeller::kSkSL, and impeller::kVulkan.

◆ TEST_P() [478/497]

impeller::testing::TEST_P ( SwapchainTransientsMTLTest  ,
CanAllocateSwapchainTextures   
)

Definition at line 27 of file swapchain_transients_mtl_unittests.mm.

27  {
28  const auto& transients = std::make_shared<SwapchainTransientsMTL>(
29  GetContext()->GetResourceAllocator());
30 
31  transients->SetSizeAndFormat({1, 1}, PixelFormat::kB8G8R8A8UNormInt);
32 
33  auto resolve = transients->GetResolveTexture();
34  EXPECT_NE(resolve, nullptr);
35  EXPECT_NE(transients->GetMSAATexture(), nullptr);
36  EXPECT_NE(transients->GetDepthStencilTexture(), nullptr);
37 
38  // Texture properties are correct for resolve.
39  EXPECT_EQ(resolve->GetTextureDescriptor().size, ISize(1, 1));
40  EXPECT_EQ(resolve->GetTextureDescriptor().format,
41  PixelFormat::kB8G8R8A8UNormInt);
42  EXPECT_EQ(resolve->GetTextureDescriptor().sample_count, SampleCount::kCount1);
43  EXPECT_EQ(resolve->GetTextureDescriptor().storage_mode,
44  StorageMode::kDevicePrivate);
45 
46  // Texture properties are correct for MSAA.
47  auto msaa = transients->GetMSAATexture();
48  EXPECT_EQ(msaa->GetTextureDescriptor().size, ISize(1, 1));
49  EXPECT_EQ(msaa->GetTextureDescriptor().format,
50  PixelFormat::kB8G8R8A8UNormInt);
51  EXPECT_EQ(msaa->GetTextureDescriptor().sample_count, SampleCount::kCount4);
52  EXPECT_EQ(msaa->GetTextureDescriptor().storage_mode,
53  StorageMode::kDeviceTransient);
54 
55  // Texture properties are correct for Depth+Stencil.
56  auto depth_stencil = transients->GetDepthStencilTexture();
57  EXPECT_EQ(depth_stencil->GetTextureDescriptor().size, ISize(1, 1));
58  EXPECT_EQ(depth_stencil->GetTextureDescriptor().format,
59  PixelFormat::kD32FloatS8UInt);
60  EXPECT_EQ(depth_stencil->GetTextureDescriptor().sample_count,
61  SampleCount::kCount4);
62  EXPECT_EQ(depth_stencil->GetTextureDescriptor().storage_mode,
63  StorageMode::kDeviceTransient);
64 
65  // Textures are cached.
66  EXPECT_EQ(transients->GetResolveTexture(), resolve);
67 
68  // Texture cache is invalidated when size changes.
69  transients->SetSizeAndFormat({2, 2}, PixelFormat::kB8G8R8A8UNormInt);
70  EXPECT_NE(resolve, transients->GetResolveTexture());
71  resolve = transients->GetResolveTexture();
72 
73  // Texture cache is invalidated when pixel format changes.
74  transients->SetSizeAndFormat({2, 2}, PixelFormat::kB10G10R10A10XR);
75  EXPECT_NE(resolve, transients->GetResolveTexture());
76 }

References impeller::kB10G10R10A10XR, impeller::kB8G8R8A8UNormInt, impeller::kCount1, impeller::kCount4, impeller::kD32FloatS8UInt, impeller::kDevicePrivate, and impeller::kDeviceTransient.

◆ TEST_P() [479/497]

impeller::testing::TEST_P ( TextContentsTest  ,
MaintainsShape   
)

Definition at line 168 of file text_contents_unittests.cc.

168  {
169  std::shared_ptr<TextFrame> text_frame =
170  MakeTextFrame("th", "ahem.ttf", /*font_size=*/50);
171 
172  std::shared_ptr<TypographerContext> context = TypographerContextSkia::Make();
173  std::shared_ptr<GlyphAtlasContext> atlas_context =
174  context->CreateGlyphAtlasContext(GlyphAtlas::Type::kAlphaBitmap);
175  std::shared_ptr<HostBuffer> host_buffer = HostBuffer::Create(
176  GetContext()->GetResourceAllocator(), GetContext()->GetIdleWaiter());
177  ASSERT_TRUE(context && context->IsValid());
178 
179  for (int i = 0; i <= 1000; ++i) {
180  Scalar font_scale = 0.440 + (i / 1000.0);
181  Rect position_rect[2];
182  Rect uv_rect[2];
183 
184  {
185  GlyphAtlasPipeline::VertexShader::PerVertexData data[12];
186  std::shared_ptr<GlyphAtlas> atlas =
187  CreateGlyphAtlas(*GetContext(), context.get(), *host_buffer,
188  GlyphAtlas::Type::kAlphaBitmap, font_scale,
189  atlas_context, text_frame);
190  ISize texture_size = atlas->GetTexture()->GetSize();
191 
192  TextContents::ComputeVertexData(
193  data, text_frame, font_scale,
194  /*entity_transform=*/Matrix::MakeScale({font_scale, font_scale, 1}),
195  /*offset=*/Vector2(0, 0),
196  /*glyph_properties=*/std::nullopt, atlas);
197  position_rect[0] = PerVertexDataPositionToRect(data);
198  uv_rect[0] = PerVertexDataUVToRect(data, texture_size);
199  position_rect[1] = PerVertexDataPositionToRect(data + 6);
200  uv_rect[1] = PerVertexDataUVToRect(data + 6, texture_size);
201  }
202  EXPECT_NEAR(GetAspectRatio(position_rect[1]), GetAspectRatio(uv_rect[1]),
203  0.001)
204  << i;
205  }
206 }
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::shared_ptr< TextFrame > &frame)

References impeller::TextContents::ComputeVertexData(), impeller::HostBuffer::Create(), CreateGlyphAtlas(), data, impeller::GlyphAtlas::kAlphaBitmap, impeller::TypographerContextSkia::Make(), and impeller::Matrix::MakeScale().

◆ TEST_P() [480/497]

impeller::testing::TEST_P ( TextContentsTest  ,
SimpleComputeVertexData   
)

Definition at line 98 of file text_contents_unittests.cc.

98  {
99 #ifndef FML_OS_MACOSX
100  GTEST_SKIP() << "Results aren't stable across linux and macos.";
101 #endif
102 
103  GlyphAtlasPipeline::VertexShader::PerVertexData data[6];
104 
105  std::shared_ptr<TextFrame> text_frame =
106  MakeTextFrame("1", "ahem.ttf", /*font_size=*/50);
107 
108  std::shared_ptr<TypographerContext> context = TypographerContextSkia::Make();
109  std::shared_ptr<GlyphAtlasContext> atlas_context =
110  context->CreateGlyphAtlasContext(GlyphAtlas::Type::kAlphaBitmap);
111  std::shared_ptr<HostBuffer> host_buffer = HostBuffer::Create(
112  GetContext()->GetResourceAllocator(), GetContext()->GetIdleWaiter());
113  ASSERT_TRUE(context && context->IsValid());
114  std::shared_ptr<GlyphAtlas> atlas =
115  CreateGlyphAtlas(*GetContext(), context.get(), *host_buffer,
116  GlyphAtlas::Type::kAlphaBitmap, /*scale=*/1.0f,
117  atlas_context, text_frame);
118 
119  ISize texture_size = atlas->GetTexture()->GetSize();
120  TextContents::ComputeVertexData(data, text_frame, /*scale=*/1.0,
121  /*entity_transform=*/Matrix(),
122  /*offset=*/Vector2(0, 0),
123  /*glyph_properties=*/std::nullopt, atlas);
124 
125  Rect position_rect = PerVertexDataPositionToRect(data);
126  Rect uv_rect = PerVertexDataUVToRect(data, texture_size);
127  // The -1 offset comes from Skia in `ComputeGlyphSize`. So since the font size
128  // is 50, the math appears to be to get back a 50x50 rect and apply 1 pixel
129  // of padding.
130  EXPECT_RECT_NEAR(position_rect, Rect::MakeXYWH(-1, -41, 52, 52));
131  EXPECT_RECT_NEAR(uv_rect, Rect::MakeXYWH(1.0, 1.0, 52, 52));
132 }

References impeller::TextContents::ComputeVertexData(), impeller::HostBuffer::Create(), CreateGlyphAtlas(), data, EXPECT_RECT_NEAR, impeller::GlyphAtlas::kAlphaBitmap, impeller::TypographerContextSkia::Make(), and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST_P() [481/497]

impeller::testing::TEST_P ( TextContentsTest  ,
SimpleComputeVertexData2x   
)

Definition at line 134 of file text_contents_unittests.cc.

134  {
135 #ifndef FML_OS_MACOSX
136  GTEST_SKIP() << "Results aren't stable across linux and macos.";
137 #endif
138 
139  GlyphAtlasPipeline::VertexShader::PerVertexData data[6];
140 
141  std::shared_ptr<TextFrame> text_frame =
142  MakeTextFrame("1", "ahem.ttf", /*font_size=*/50);
143 
144  std::shared_ptr<TypographerContext> context = TypographerContextSkia::Make();
145  std::shared_ptr<GlyphAtlasContext> atlas_context =
146  context->CreateGlyphAtlasContext(GlyphAtlas::Type::kAlphaBitmap);
147  std::shared_ptr<HostBuffer> host_buffer = HostBuffer::Create(
148  GetContext()->GetResourceAllocator(), GetContext()->GetIdleWaiter());
149  ASSERT_TRUE(context && context->IsValid());
150  Scalar font_scale = 2.f;
151  std::shared_ptr<GlyphAtlas> atlas = CreateGlyphAtlas(
152  *GetContext(), context.get(), *host_buffer,
153  GlyphAtlas::Type::kAlphaBitmap, font_scale, atlas_context, text_frame);
154 
155  ISize texture_size = atlas->GetTexture()->GetSize();
156  TextContents::ComputeVertexData(
157  data, text_frame, font_scale,
158  /*entity_transform=*/Matrix::MakeScale({font_scale, font_scale, 1}),
159  /*offset=*/Vector2(0, 0),
160  /*glyph_properties=*/std::nullopt, atlas);
161 
162  Rect position_rect = PerVertexDataPositionToRect(data);
163  Rect uv_rect = PerVertexDataUVToRect(data, texture_size);
164  EXPECT_RECT_NEAR(position_rect, Rect::MakeXYWH(-1, -81, 102, 102));
165  EXPECT_RECT_NEAR(uv_rect, Rect::MakeXYWH(1.0, 1.0, 102, 102));
166 }

References impeller::TextContents::ComputeVertexData(), impeller::HostBuffer::Create(), CreateGlyphAtlas(), data, EXPECT_RECT_NEAR, impeller::GlyphAtlas::kAlphaBitmap, impeller::TypographerContextSkia::Make(), impeller::Matrix::MakeScale(), and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST_P() [482/497]

impeller::testing::TEST_P ( TypographerTest  ,
CanConvertTextBlob   
)

Definition at line 62 of file typographer_unittests.cc.

62  {
63  SkFont font = flutter::testing::CreateTestFontOfSize(12);
64  auto blob = SkTextBlob::MakeFromString(
65  "the quick brown fox jumped over the lazy dog.", font);
66  ASSERT_TRUE(blob);
67  auto frame = MakeTextFrameFromTextBlobSkia(blob);
68  ASSERT_EQ(frame->GetRunCount(), 1u);
69  for (const auto& run : frame->GetRuns()) {
70  ASSERT_TRUE(run.IsValid());
71  ASSERT_EQ(run.GetGlyphCount(), 45u);
72  }
73 }

References impeller::MakeTextFrameFromTextBlobSkia().

◆ TEST_P() [483/497]

impeller::testing::TEST_P ( TypographerTest  ,
CanCreateGlyphAtlas   
)

Definition at line 80 of file typographer_unittests.cc.

80  {
81  auto context = TypographerContextSkia::Make();
82  auto atlas_context =
83  context->CreateGlyphAtlasContext(GlyphAtlas::Type::kAlphaBitmap);
84  auto host_buffer = HostBuffer::Create(GetContext()->GetResourceAllocator(),
85  GetContext()->GetIdleWaiter());
86  ASSERT_TRUE(context && context->IsValid());
87  SkFont sk_font = flutter::testing::CreateTestFontOfSize(12);
88  auto blob = SkTextBlob::MakeFromString("hello", sk_font);
89  ASSERT_TRUE(blob);
90  auto atlas =
91  CreateGlyphAtlas(*GetContext(), context.get(), *host_buffer,
92  GlyphAtlas::Type::kAlphaBitmap, 1.0f, atlas_context,
94 
95  ASSERT_NE(atlas, nullptr);
96  ASSERT_NE(atlas->GetTexture(), nullptr);
97  ASSERT_EQ(atlas->GetType(), GlyphAtlas::Type::kAlphaBitmap);
98  ASSERT_EQ(atlas->GetGlyphCount(), 4llu);
99 
100  std::optional<impeller::ScaledFont> first_scaled_font;
101  std::optional<impeller::SubpixelGlyph> first_glyph;
102  Rect first_rect;
103  atlas->IterateGlyphs([&](const ScaledFont& scaled_font,
104  const SubpixelGlyph& glyph,
105  const Rect& rect) -> bool {
106  first_scaled_font = scaled_font;
107  first_glyph = glyph;
108  first_rect = rect;
109  return false;
110  });
111 
112  ASSERT_TRUE(first_scaled_font.has_value());
113  ASSERT_TRUE(atlas
114  ->FindFontGlyphBounds(
115  {first_scaled_font.value(), first_glyph.value()})
116  .has_value());
117 }
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< std::optional< GlyphProperties >> &properties)

References impeller::HostBuffer::Create(), CreateGlyphAtlas(), impeller::GlyphAtlas::kAlphaBitmap, impeller::TypographerContextSkia::Make(), and impeller::MakeTextFrameFromTextBlobSkia().

◆ TEST_P() [484/497]

impeller::testing::TEST_P ( TypographerTest  ,
CanCreateRenderContext   
)

Definition at line 75 of file typographer_unittests.cc.

75  {
76  auto context = TypographerContextSkia::Make();
77  ASSERT_TRUE(context && context->IsValid());
78 }

References impeller::TypographerContextSkia::Make().

◆ TEST_P() [485/497]

impeller::testing::TEST_P ( TypographerTest  ,
GlyphAtlasIsRecycledIfUnchanged   
)

Definition at line 180 of file typographer_unittests.cc.

180  {
181  auto context = TypographerContextSkia::Make();
182  auto atlas_context =
183  context->CreateGlyphAtlasContext(GlyphAtlas::Type::kAlphaBitmap);
184  auto host_buffer = HostBuffer::Create(GetContext()->GetResourceAllocator(),
185  GetContext()->GetIdleWaiter());
186  ASSERT_TRUE(context && context->IsValid());
187  SkFont sk_font = flutter::testing::CreateTestFontOfSize(12);
188  auto blob = SkTextBlob::MakeFromString("spooky skellingtons", sk_font);
189  ASSERT_TRUE(blob);
190  auto atlas =
191  CreateGlyphAtlas(*GetContext(), context.get(), *host_buffer,
192  GlyphAtlas::Type::kAlphaBitmap, 1.0f, atlas_context,
194  ASSERT_NE(atlas, nullptr);
195  ASSERT_NE(atlas->GetTexture(), nullptr);
196  ASSERT_EQ(atlas, atlas_context->GetGlyphAtlas());
197 
198  // now attempt to re-create an atlas with the same text blob.
199 
200  auto next_atlas =
201  CreateGlyphAtlas(*GetContext(), context.get(), *host_buffer,
202  GlyphAtlas::Type::kAlphaBitmap, 1.0f, atlas_context,
204  ASSERT_EQ(atlas, next_atlas);
205  ASSERT_EQ(atlas_context->GetGlyphAtlas(), atlas);
206 }

References impeller::HostBuffer::Create(), CreateGlyphAtlas(), impeller::GlyphAtlas::kAlphaBitmap, impeller::TypographerContextSkia::Make(), and impeller::MakeTextFrameFromTextBlobSkia().

◆ TEST_P() [486/497]

impeller::testing::TEST_P ( TypographerTest  ,
GlyphAtlasTextureIsRecycledIfUnchanged   
)

Definition at line 256 of file typographer_unittests.cc.

256  {
257  auto host_buffer = HostBuffer::Create(GetContext()->GetResourceAllocator(),
258  GetContext()->GetIdleWaiter());
259  auto context = TypographerContextSkia::Make();
260  auto atlas_context =
261  context->CreateGlyphAtlasContext(GlyphAtlas::Type::kAlphaBitmap);
262  ASSERT_TRUE(context && context->IsValid());
263  SkFont sk_font = flutter::testing::CreateTestFontOfSize(12);
264  auto blob = SkTextBlob::MakeFromString("spooky 1", sk_font);
265  ASSERT_TRUE(blob);
266  auto atlas =
267  CreateGlyphAtlas(*GetContext(), context.get(), *host_buffer,
268  GlyphAtlas::Type::kAlphaBitmap, 1.0f, atlas_context,
270  auto old_packer = atlas_context->GetRectPacker();
271 
272  ASSERT_NE(atlas, nullptr);
273  ASSERT_NE(atlas->GetTexture(), nullptr);
274  ASSERT_EQ(atlas, atlas_context->GetGlyphAtlas());
275 
276  auto* first_texture = atlas->GetTexture().get();
277 
278  // Now create a new glyph atlas with a nearly identical blob.
279 
280  auto blob2 = SkTextBlob::MakeFromString("spooky 2", sk_font);
281  auto next_atlas =
282  CreateGlyphAtlas(*GetContext(), context.get(), *host_buffer,
283  GlyphAtlas::Type::kAlphaBitmap, 1.0f, atlas_context,
285  ASSERT_EQ(atlas, next_atlas);
286  auto* second_texture = next_atlas->GetTexture().get();
287 
288  auto new_packer = atlas_context->GetRectPacker();
289 
290  ASSERT_EQ(second_texture, first_texture);
291  ASSERT_EQ(old_packer, new_packer);
292 }

References impeller::HostBuffer::Create(), CreateGlyphAtlas(), impeller::GlyphAtlas::kAlphaBitmap, impeller::TypographerContextSkia::Make(), and impeller::MakeTextFrameFromTextBlobSkia().

◆ TEST_P() [487/497]

impeller::testing::TEST_P ( TypographerTest  ,
GlyphAtlasTextureWillGrowTilMaxTextureSize   
)

Definition at line 425 of file typographer_unittests.cc.

425  {
426  if (GetBackend() == PlaygroundBackend::kOpenGLES) {
427  GTEST_SKIP() << "Atlas growth isn't supported for OpenGLES currently.";
428  }
429 
430  auto host_buffer = HostBuffer::Create(GetContext()->GetResourceAllocator(),
431  GetContext()->GetIdleWaiter());
432  auto context = TypographerContextSkia::Make();
433  auto atlas_context =
434  context->CreateGlyphAtlasContext(GlyphAtlas::Type::kAlphaBitmap);
435  ASSERT_TRUE(context && context->IsValid());
436  SkFont sk_font = flutter::testing::CreateTestFontOfSize(12);
437  auto blob = SkTextBlob::MakeFromString("A", sk_font);
438  ASSERT_TRUE(blob);
439  auto atlas =
440  CreateGlyphAtlas(*GetContext(), context.get(), *host_buffer,
441  GlyphAtlas::Type::kAlphaBitmap, 1.0f, atlas_context,
443  // Continually append new glyphs until the glyph size grows to the maximum.
444  // Note that the sizes here are more or less experimentally determined, but
445  // the important expectation is that the atlas size will shrink again after
446  // growing to the maximum size.
447  constexpr ISize expected_sizes[13] = {
448  {4096, 4096}, //
449  {4096, 4096}, //
450  {4096, 8192}, //
451  {4096, 8192}, //
452  {4096, 8192}, //
453  {4096, 8192}, //
454  {4096, 16384}, //
455  {4096, 16384}, //
456  {4096, 16384}, //
457  {4096, 16384}, //
458  {4096, 16384}, //
459  {4096, 16384}, //
460  {4096, 4096} // Shrinks!
461  };
462 
463  SkFont sk_font_small = flutter::testing::CreateTestFontOfSize(10);
464 
465  for (int i = 0; i < 13; i++) {
466  SkTextBlobBuilder builder;
467 
468  auto add_char = [&](const SkFont& sk_font, char c) {
469  int count = sk_font.countText(&c, 1, SkTextEncoding::kUTF8);
470  auto buffer = builder.allocRunPos(sk_font, count);
471  sk_font.textToGlyphs(&c, 1, SkTextEncoding::kUTF8, buffer.glyphs, count);
472  sk_font.getPos(buffer.glyphs, count, buffer.points(), {0, 0});
473  };
474 
475  SkFont sk_font = flutter::testing::CreateTestFontOfSize(50 + i);
476  add_char(sk_font, 'A');
477  add_char(sk_font_small, 'B');
478  auto blob = builder.make();
479 
480  atlas =
481  CreateGlyphAtlas(*GetContext(), context.get(), *host_buffer,
482  GlyphAtlas::Type::kAlphaBitmap, 50 + i, atlas_context,
484  ASSERT_TRUE(!!atlas);
485  EXPECT_EQ(atlas->GetTexture()->GetTextureDescriptor().size,
486  expected_sizes[i]);
487  }
488 
489  // The final atlas should contain both the "A" glyph (which was not present
490  // in the previous atlas) and the "B" glyph (which existed in the previous
491  // atlas).
492  ASSERT_EQ(atlas->GetGlyphCount(), 2u);
493 }

References impeller::HostBuffer::Create(), CreateGlyphAtlas(), impeller::GlyphAtlas::kAlphaBitmap, impeller::kOpenGLES, impeller::TypographerContextSkia::Make(), and impeller::MakeTextFrameFromTextBlobSkia().

◆ TEST_P() [488/497]

impeller::testing::TEST_P ( TypographerTest  ,
GlyphAtlasWithLotsOfdUniqueGlyphSize   
)

Definition at line 208 of file typographer_unittests.cc.

208  {
209  auto host_buffer = HostBuffer::Create(GetContext()->GetResourceAllocator(),
210  GetContext()->GetIdleWaiter());
211  auto context = TypographerContextSkia::Make();
212  auto atlas_context =
213  context->CreateGlyphAtlasContext(GlyphAtlas::Type::kAlphaBitmap);
214  ASSERT_TRUE(context && context->IsValid());
215 
216  const char* test_string =
217  "QWERTYUIOPASDFGHJKLZXCVBNMqewrtyuiopasdfghjklzxcvbnm,.<>[]{};':"
218  "2134567890-=!@#$%^&*()_+"
219  "œ∑´®†¥¨ˆøπ““‘‘åß∂ƒ©˙∆˚¬…æ≈ç√∫˜µ≤≥≥≥≥÷¡™£¢∞§¶•ªº–≠⁄€‹›fifl‡°·‚—±Œ„´‰Á¨Ø∏”’/"
220  "* Í˝ */¸˛Ç◊ı˜Â¯˘¿";
221 
222  SkFont sk_font = flutter::testing::CreateTestFontOfSize(12);
223  auto blob = SkTextBlob::MakeFromString(test_string, sk_font);
224  ASSERT_TRUE(blob);
225 
226  size_t size_count = 8;
227  std::vector<std::shared_ptr<TextFrame>> frames;
228  for (size_t index = 0; index < size_count; index += 1) {
229  frames.push_back(MakeTextFrameFromTextBlobSkia(blob));
230  frames.back()->SetPerFrameData(0.6 * index, {0, 0}, Matrix(), {});
231  };
232  auto atlas =
233  context->CreateGlyphAtlas(*GetContext(), GlyphAtlas::Type::kAlphaBitmap,
234  *host_buffer, atlas_context, frames);
235  ASSERT_NE(atlas, nullptr);
236  ASSERT_NE(atlas->GetTexture(), nullptr);
237 
238  std::set<uint16_t> unique_glyphs;
239  std::vector<uint16_t> total_glyphs;
240  atlas->IterateGlyphs([&](const ScaledFont& scaled_font,
241  const SubpixelGlyph& glyph, const Rect& rect) {
242  unique_glyphs.insert(glyph.glyph.index);
243  total_glyphs.push_back(glyph.glyph.index);
244  return true;
245  });
246 
247  // These numbers may be different due to subpixel positions.
248  EXPECT_LE(unique_glyphs.size() * size_count, atlas->GetGlyphCount());
249  EXPECT_EQ(total_glyphs.size(), atlas->GetGlyphCount());
250 
251  EXPECT_TRUE(atlas->GetGlyphCount() > 0);
252  EXPECT_TRUE(atlas->GetTexture()->GetSize().width > 0);
253  EXPECT_TRUE(atlas->GetTexture()->GetSize().height > 0);
254 }

References impeller::HostBuffer::Create(), impeller::SubpixelGlyph::glyph, impeller::Glyph::index, impeller::GlyphAtlas::kAlphaBitmap, impeller::TypographerContextSkia::Make(), and impeller::MakeTextFrameFromTextBlobSkia().

◆ TEST_P() [489/497]

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  GetContext()->GetIdleWaiter());
165  ASSERT_TRUE(context && context->IsValid());
166  SkFont sk_font = flutter::testing::CreateTestFontOfSize(12);
167  auto blob = SkTextBlob::MakeFromString("AGH", sk_font);
168  ASSERT_TRUE(blob);
169  auto atlas =
170  CreateGlyphAtlas(*GetContext(), context.get(), *host_buffer,
171  GlyphAtlas::Type::kAlphaBitmap, 1.0f, atlas_context,
173  ASSERT_NE(atlas, nullptr);
174  ASSERT_NE(atlas->GetTexture(), nullptr);
175 
176  EXPECT_EQ(atlas->GetTexture()->GetSize().width, 4096u);
177  EXPECT_EQ(atlas->GetTexture()->GetSize().height, 1024u);
178 }

References impeller::HostBuffer::Create(), CreateGlyphAtlas(), impeller::GlyphAtlas::kAlphaBitmap, impeller::TypographerContextSkia::Make(), and impeller::MakeTextFrameFromTextBlobSkia().

◆ TEST_P() [490/497]

impeller::testing::TEST_P ( TypographerTest  ,
GlyphColorIsIgnoredForNonEmojiFonts   
)

Definition at line 329 of file typographer_unittests.cc.

329  {
330  auto host_buffer = HostBuffer::Create(GetContext()->GetResourceAllocator(),
331  GetContext()->GetIdleWaiter());
332  sk_sp<SkFontMgr> font_mgr = txt::GetDefaultFontManager();
333  sk_sp<SkTypeface> typeface =
334  font_mgr->matchFamilyStyle("Arial", SkFontStyle::Normal());
335  SkFont sk_font(typeface, 0.5f);
336 
337  auto context = TypographerContextSkia::Make();
338  auto atlas_context =
339  context->CreateGlyphAtlasContext(GlyphAtlas::Type::kColorBitmap);
340 
341  // Create two frames with the same character and a different color, but as a
342  // non-emoji font the text frame constructor will ignore it.
343  auto frame =
344  MakeTextFrameFromTextBlobSkia(SkTextBlob::MakeFromString("A", sk_font));
345  auto frame_2 =
346  MakeTextFrameFromTextBlobSkia(SkTextBlob::MakeFromString("A", sk_font));
347  std::vector<std::optional<GlyphProperties>> properties = {
348  GlyphProperties{},
349  GlyphProperties{},
350  };
351 
352  auto next_atlas =
353  CreateGlyphAtlas(*GetContext(), context.get(), *host_buffer,
354  GlyphAtlas::Type::kColorBitmap, 1.0f, atlas_context,
355  {frame, frame_2}, properties);
356 
357  EXPECT_EQ(next_atlas->GetGlyphCount(), 1u);
358 }

References impeller::HostBuffer::Create(), CreateGlyphAtlas(), impeller::GlyphAtlas::kColorBitmap, impeller::TypographerContextSkia::Make(), and impeller::MakeTextFrameFromTextBlobSkia().

◆ TEST_P() [491/497]

impeller::testing::TEST_P ( TypographerTest  ,
GlyphColorIsPartOfCacheKey   
)

Definition at line 294 of file typographer_unittests.cc.

294  {
295  auto host_buffer = HostBuffer::Create(GetContext()->GetResourceAllocator(),
296  GetContext()->GetIdleWaiter());
297 #if FML_OS_MACOSX
298  auto mapping = flutter::testing::OpenFixtureAsSkData("Apple Color Emoji.ttc");
299 #else
300  auto mapping = flutter::testing::OpenFixtureAsSkData("NotoColorEmoji.ttf");
301 #endif
302  ASSERT_TRUE(mapping);
303  sk_sp<SkFontMgr> font_mgr = txt::GetDefaultFontManager();
304  SkFont emoji_font(font_mgr->makeFromData(mapping), 50.0);
305 
306  auto context = TypographerContextSkia::Make();
307  auto atlas_context =
308  context->CreateGlyphAtlasContext(GlyphAtlas::Type::kColorBitmap);
309 
310  // Create two frames with the same character and a different color, expect
311  // that it adds a character.
312  auto frame = MakeTextFrameFromTextBlobSkia(
313  SkTextBlob::MakeFromString("😂", emoji_font));
314  auto frame_2 = MakeTextFrameFromTextBlobSkia(
315  SkTextBlob::MakeFromString("😂", emoji_font));
316  std::vector<std::optional<GlyphProperties>> properties = {
317  GlyphProperties{.color = Color::Red()},
318  GlyphProperties{.color = Color::Blue()},
319  };
320 
321  auto next_atlas =
322  CreateGlyphAtlas(*GetContext(), context.get(), *host_buffer,
323  GlyphAtlas::Type::kColorBitmap, 1.0f, atlas_context,
324  {frame, frame_2}, properties);
325 
326  EXPECT_EQ(next_atlas->GetGlyphCount(), 2u);
327 }

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() [492/497]

impeller::testing::TEST_P ( TypographerTest  ,
InvalidAtlasForcesRepopulation   
)

Definition at line 615 of file typographer_unittests.cc.

615  {
616  SkFont font = flutter::testing::CreateTestFontOfSize(12);
617  auto blob = SkTextBlob::MakeFromString(
618  "the quick brown fox jumped over the lazy dog.", font);
619  ASSERT_TRUE(blob);
620  auto frame = MakeTextFrameFromTextBlobSkia(blob);
621 
622  EXPECT_FALSE(frame->IsFrameComplete());
623 
624  auto context = TypographerContextSkia::Make();
625  auto atlas_context =
626  context->CreateGlyphAtlasContext(GlyphAtlas::Type::kAlphaBitmap);
627  auto host_buffer = HostBuffer::Create(GetContext()->GetResourceAllocator(),
628  GetContext()->GetIdleWaiter());
629 
630  auto atlas = CreateGlyphAtlas(*GetContext(), context.get(), *host_buffer,
631  GlyphAtlas::Type::kAlphaBitmap, /*scale=*/1.0f,
632  atlas_context, frame);
633 
634  // The glyph position in the atlas was not known when this value
635  // was recorded. It is marked as a placeholder.
636  EXPECT_TRUE(frame->IsFrameComplete());
637  EXPECT_TRUE(frame->GetFrameBounds(0).is_placeholder);
638  if (GetBackend() == PlaygroundBackend::kOpenGLES) {
639  // OpenGLES must always increase the atlas backend if the texture grows.
640  EXPECT_EQ(frame->GetAtlasGenerationAndID().first, 1u);
641  } else {
642  EXPECT_EQ(frame->GetAtlasGenerationAndID().first, 0u);
643  }
644 
645  auto second_context = TypographerContextSkia::Make();
646  auto second_atlas_context =
647  second_context->CreateGlyphAtlasContext(GlyphAtlas::Type::kAlphaBitmap);
648 
649  EXPECT_FALSE(second_atlas_context->GetGlyphAtlas()->IsValid());
650 
651  atlas = CreateGlyphAtlas(*GetContext(), second_context.get(), *host_buffer,
652  GlyphAtlas::Type::kAlphaBitmap, /*scale=*/1.0f,
653  second_atlas_context, frame);
654 
655  EXPECT_TRUE(second_atlas_context->GetGlyphAtlas()->IsValid());
656 }

References impeller::HostBuffer::Create(), CreateGlyphAtlas(), impeller::GlyphAtlas::kAlphaBitmap, impeller::kOpenGLES, impeller::TypographerContextSkia::Make(), and impeller::MakeTextFrameFromTextBlobSkia().

◆ TEST_P() [493/497]

impeller::testing::TEST_P ( TypographerTest  ,
LazyAtlasTracksColor   
)

Definition at line 119 of file typographer_unittests.cc.

119  {
120  auto host_buffer = HostBuffer::Create(GetContext()->GetResourceAllocator(),
121  GetContext()->GetIdleWaiter());
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}, Matrix(), {});
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}, Matrix(), {});
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() [494/497]

impeller::testing::TEST_P ( TypographerTest  ,
RectanglePackerAddsNonoverlapingRectangles   
)

Definition at line 360 of file typographer_unittests.cc.

360  {
361  auto packer = RectanglePacker::Factory(200, 100);
362  ASSERT_NE(packer, nullptr);
363  ASSERT_EQ(packer->PercentFull(), 0);
364 
365  const SkIRect packer_area = SkIRect::MakeXYWH(0, 0, 200, 100);
366 
367  IPoint16 first_output = {-1, -1}; // Fill with sentinel values
368  ASSERT_TRUE(packer->AddRect(20, 20, &first_output));
369  // Make sure the rectangle is placed such that it is inside the bounds of
370  // the packer's area.
371  const SkIRect first_rect =
372  SkIRect::MakeXYWH(first_output.x(), first_output.y(), 20, 20);
373  ASSERT_TRUE(SkIRect::Intersects(packer_area, first_rect));
374 
375  // Initial area was 200 x 100 = 20_000
376  // We added 20x20 = 400. 400 / 20_000 == 0.02 == 2%
377  ASSERT_TRUE(flutter::testing::NumberNear(packer->PercentFull(), 0.02));
378 
379  IPoint16 second_output = {-1, -1};
380  ASSERT_TRUE(packer->AddRect(140, 90, &second_output));
381  const SkIRect second_rect =
382  SkIRect::MakeXYWH(second_output.x(), second_output.y(), 140, 90);
383  // Make sure the rectangle is placed such that it is inside the bounds of
384  // the packer's area but not in the are of the first rectangle.
385  ASSERT_TRUE(SkIRect::Intersects(packer_area, second_rect));
386  ASSERT_FALSE(SkIRect::Intersects(first_rect, second_rect));
387 
388  // We added another 90 x 140 = 12_600 units, now taking us to 13_000
389  // 13_000 / 20_000 == 0.65 == 65%
390  ASSERT_TRUE(flutter::testing::NumberNear(packer->PercentFull(), 0.65));
391 
392  // There's enough area to add this rectangle, but no space big enough for
393  // the 50 units of width.
394  IPoint16 output;
395  ASSERT_FALSE(packer->AddRect(50, 50, &output));
396  // Should be unchanged.
397  ASSERT_TRUE(flutter::testing::NumberNear(packer->PercentFull(), 0.65));
398 
399  packer->Reset();
400  // Should be empty now.
401  ASSERT_EQ(packer->PercentFull(), 0);
402 }
bool NumberNear(double a, double b)

References impeller::RectanglePacker::Factory(), NumberNear(), impeller::IPoint16::x(), and impeller::IPoint16::y().

◆ TEST_P() [495/497]

impeller::testing::TEST_P ( TypographerTest  ,
TextFrameAtlasGenerationTracksState   
)

Definition at line 563 of file typographer_unittests.cc.

563  {
564  SkFont font = flutter::testing::CreateTestFontOfSize(12);
565  auto blob = SkTextBlob::MakeFromString(
566  "the quick brown fox jumped over the lazy dog.", font);
567  ASSERT_TRUE(blob);
568  auto frame = MakeTextFrameFromTextBlobSkia(blob);
569 
570  EXPECT_FALSE(frame->IsFrameComplete());
571 
572  auto context = TypographerContextSkia::Make();
573  auto atlas_context =
574  context->CreateGlyphAtlasContext(GlyphAtlas::Type::kAlphaBitmap);
575  auto host_buffer = HostBuffer::Create(GetContext()->GetResourceAllocator(),
576  GetContext()->GetIdleWaiter());
577 
578  auto atlas = CreateGlyphAtlas(*GetContext(), context.get(), *host_buffer,
579  GlyphAtlas::Type::kAlphaBitmap, /*scale=*/1.0f,
580  atlas_context, frame);
581 
582  // The glyph position in the atlas was not known when this value
583  // was recorded. It is marked as a placeholder.
584  EXPECT_TRUE(frame->IsFrameComplete());
585  EXPECT_TRUE(frame->GetFrameBounds(0).is_placeholder);
586  if (GetBackend() == PlaygroundBackend::kOpenGLES) {
587  // OpenGLES must always increase the atlas backend if the texture grows.
588  EXPECT_EQ(frame->GetAtlasGenerationAndID().first, 1u);
589  } else {
590  EXPECT_EQ(frame->GetAtlasGenerationAndID().first, 0u);
591  }
592 
593  atlas = CreateGlyphAtlas(*GetContext(), context.get(), *host_buffer,
594  GlyphAtlas::Type::kAlphaBitmap, /*scale=*/1.0f,
595  atlas_context, frame);
596 
597  // The second time the glyph is rendered, the bounds are correcly known.
598  EXPECT_TRUE(frame->IsFrameComplete());
599  EXPECT_FALSE(frame->GetFrameBounds(0).is_placeholder);
600  if (GetBackend() == PlaygroundBackend::kOpenGLES) {
601  EXPECT_EQ(frame->GetAtlasGenerationAndID().first, 1u);
602  } else {
603  EXPECT_EQ(frame->GetAtlasGenerationAndID().first, 0u);
604  }
605 
606  // Force increase the generation.
607  atlas_context->GetGlyphAtlas()->SetAtlasGeneration(2u);
608  atlas = CreateGlyphAtlas(*GetContext(), context.get(), *host_buffer,
609  GlyphAtlas::Type::kAlphaBitmap, /*scale=*/1.0f,
610  atlas_context, frame);
611 
612  EXPECT_EQ(frame->GetAtlasGenerationAndID().first, 2u);
613 }

References impeller::HostBuffer::Create(), CreateGlyphAtlas(), impeller::GlyphAtlas::kAlphaBitmap, impeller::kOpenGLES, impeller::TypographerContextSkia::Make(), and impeller::MakeTextFrameFromTextBlobSkia().

◆ TEST_P() [496/497]

impeller::testing::TEST_P ( TypographerTest  ,
TextFrameInitialBoundsArePlaceholder   
)

Definition at line 495 of file typographer_unittests.cc.

495  {
496  SkFont font = flutter::testing::CreateTestFontOfSize(12);
497  auto blob = SkTextBlob::MakeFromString(
498  "the quick brown fox jumped over the lazy dog.", font);
499  ASSERT_TRUE(blob);
500  auto frame = MakeTextFrameFromTextBlobSkia(blob);
501 
502  EXPECT_FALSE(frame->IsFrameComplete());
503 
504  auto context = TypographerContextSkia::Make();
505  auto atlas_context =
506  context->CreateGlyphAtlasContext(GlyphAtlas::Type::kAlphaBitmap);
507  auto host_buffer = HostBuffer::Create(GetContext()->GetResourceAllocator(),
508  GetContext()->GetIdleWaiter());
509 
510  auto atlas = CreateGlyphAtlas(*GetContext(), context.get(), *host_buffer,
511  GlyphAtlas::Type::kAlphaBitmap, /*scale=*/1.0f,
512  atlas_context, frame);
513 
514  // The glyph position in the atlas was not known when this value
515  // was recorded. It is marked as a placeholder.
516  EXPECT_TRUE(frame->IsFrameComplete());
517  EXPECT_TRUE(frame->GetFrameBounds(0).is_placeholder);
518 
519  atlas = CreateGlyphAtlas(*GetContext(), context.get(), *host_buffer,
520  GlyphAtlas::Type::kAlphaBitmap, /*scale=*/1.0f,
521  atlas_context, frame);
522 
523  // The second time the glyph is rendered, the bounds are correcly known.
524  EXPECT_TRUE(frame->IsFrameComplete());
525  EXPECT_FALSE(frame->GetFrameBounds(0).is_placeholder);
526 }

References impeller::HostBuffer::Create(), CreateGlyphAtlas(), impeller::GlyphAtlas::kAlphaBitmap, impeller::TypographerContextSkia::Make(), and impeller::MakeTextFrameFromTextBlobSkia().

◆ TEST_P() [497/497]

impeller::testing::TEST_P ( TypographerTest  ,
TextFrameInvalidationWithScale   
)

Definition at line 528 of file typographer_unittests.cc.

528  {
529  SkFont font = flutter::testing::CreateTestFontOfSize(12);
530  auto blob = SkTextBlob::MakeFromString(
531  "the quick brown fox jumped over the lazy dog.", font);
532  ASSERT_TRUE(blob);
533  auto frame = MakeTextFrameFromTextBlobSkia(blob);
534 
535  EXPECT_FALSE(frame->IsFrameComplete());
536 
537  auto context = TypographerContextSkia::Make();
538  auto atlas_context =
539  context->CreateGlyphAtlasContext(GlyphAtlas::Type::kAlphaBitmap);
540  auto host_buffer = HostBuffer::Create(GetContext()->GetResourceAllocator(),
541  GetContext()->GetIdleWaiter());
542 
543  auto atlas = CreateGlyphAtlas(*GetContext(), context.get(), *host_buffer,
544  GlyphAtlas::Type::kAlphaBitmap, /*scale=*/1.0f,
545  atlas_context, frame);
546 
547  // The glyph position in the atlas was not known when this value
548  // was recorded. It is marked as a placeholder.
549  EXPECT_TRUE(frame->IsFrameComplete());
550  EXPECT_TRUE(frame->GetFrameBounds(0).is_placeholder);
551 
552  // Change the scale and the glyph data will still be a placeholder, as the
553  // old data is no longer valid.
554  atlas = CreateGlyphAtlas(*GetContext(), context.get(), *host_buffer,
555  GlyphAtlas::Type::kAlphaBitmap, /*scale=*/2.0f,
556  atlas_context, frame);
557 
558  // The second time the glyph is rendered, the bounds are correcly known.
559  EXPECT_TRUE(frame->IsFrameComplete());
560  EXPECT_TRUE(frame->GetFrameBounds(0).is_placeholder);
561 }

References impeller::HostBuffer::Create(), CreateGlyphAtlas(), impeller::GlyphAtlas::kAlphaBitmap, impeller::TypographerContextSkia::Make(), and impeller::MakeTextFrameFromTextBlobSkia().

◆ toColor()

flutter::DlColor impeller::testing::toColor ( const float *  components)

Definition at line 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 288 of file aiks_dl_text_unittests.cc.

Referenced by TEST_P().

◆ kMagicFailingAllocation

constexpr const size_t impeller::testing::kMagicFailingAllocation = 1024000 * 2
staticconstexpr

◆ kPaintVariations

const std::map<std::string, MaskBlurTestConfig> impeller::testing::kPaintVariations
static

Definition at line 587 of file aiks_dl_blur_unittests.cc.