Flutter Impeller
impeller::testing Namespace Reference

Classes

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

Typedefs

using AiksTest = AiksPlayground
 
using DisplayListTest = DlPlayground
 
using EntityTest = EntityPlayground
 
using HostBufferTest = EntityPlayground
 
using EntityPassTargetTest = EntityPlayground
 
using RenderTargetCacheTest = EntityPlayground
 
using SaveLayerUtilsTest = ::testing::Test
 
using AllocatorMTLTest = PlaygroundTest
 
using DriverInfoVKTest = PlaygroundTest
 
using PipelineCacheDataVKPlaygroundTest = PlaygroundTest
 
using RendererTest = PlaygroundTest
 
using BlitPassTest = PlaygroundTest
 
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_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, 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)
 
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, 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, 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)
 
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, CanRenderNestedClips)
 
 TEST_P (AiksTest, CanRenderDifferenceClips)
 
 TEST_P (AiksTest, CanRenderWithContiguousClipRestores)
 
 TEST_P (AiksTest, ClipsUseCurrentTransform)
 
 TEST_P (AiksTest, FramebufferBlendsRespectClips)
 
 TEST_P (AiksTest, CanRenderLinearGradientClamp)
 
 TEST_P (AiksTest, CanRenderLinearGradientRepeat)
 
 TEST_P (AiksTest, CanRenderLinearGradientMirror)
 
 TEST_P (AiksTest, CanRenderLinearGradientDecal)
 
 TEST_P (AiksTest, CanRenderLinearGradientDecalWithColorFilter)
 
static void CanRenderLinearGradientWithDithering (AiksTest *aiks_test)
 
 TEST_P (AiksTest, CanRenderLinearGradientWithDitheringEnabled)
 
static void CanRenderRadialGradientWithDithering (AiksTest *aiks_test)
 
 TEST_P (AiksTest, CanRenderRadialGradientWithDitheringEnabled)
 
static void CanRenderSweepGradientWithDithering (AiksTest *aiks_test)
 
 TEST_P (AiksTest, CanRenderSweepGradientWithDitheringEnabled)
 
static void CanRenderConicalGradientWithDithering (AiksTest *aiks_test)
 
 TEST_P (AiksTest, CanRenderConicalGradientWithDitheringEnabled)
 
 TEST_P (AiksTest, CanRenderLinearGradientWithOverlappingStopsClamp)
 
 TEST_P (AiksTest, CanRenderLinearGradientManyColorsClamp)
 
 TEST_P (AiksTest, CanRenderLinearGradientManyColorsRepeat)
 
 TEST_P (AiksTest, CanRenderLinearGradientManyColorsMirror)
 
 TEST_P (AiksTest, CanRenderLinearGradientManyColorsDecal)
 
 TEST_P (AiksTest, CanRenderLinearGradientWayManyColorsClamp)
 
 TEST_P (AiksTest, CanRenderLinearGradientManyColorsUnevenStops)
 
 TEST_P (AiksTest, CanRenderLinearGradientMaskBlur)
 
 TEST_P (AiksTest, CanRenderRadialGradient)
 
 TEST_P (AiksTest, CanRenderRadialGradientManyColors)
 
 TEST_P (AiksTest, CanRenderSweepGradientClamp)
 
 TEST_P (AiksTest, CanRenderSweepGradientRepeat)
 
 TEST_P (AiksTest, CanRenderSweepGradientMirror)
 
 TEST_P (AiksTest, CanRenderSweepGradientDecal)
 
 TEST_P (AiksTest, CanRenderSweepGradientManyColorsClamp)
 
 TEST_P (AiksTest, CanRenderSweepGradientManyColorsRepeat)
 
 TEST_P (AiksTest, CanRenderSweepGradientManyColorsMirror)
 
 TEST_P (AiksTest, CanRenderSweepGradientManyColorsDecal)
 
 TEST_P (AiksTest, CanRenderConicalGradient)
 
 TEST_P (AiksTest, CanRenderGradientDecalWithBackground)
 
 TEST_P (AiksTest, GradientStrokesRenderCorrectly)
 
 TEST_P (AiksTest, FastGradientTestHorizontal)
 
 TEST_P (AiksTest, FastGradientTestVertical)
 
 TEST_P (AiksTest, FastGradientTestHorizontalReversed)
 
 TEST_P (AiksTest, FastGradientTestVerticalReversed)
 
 TEST_P (AiksTest, VerifyNonOptimizedGradient)
 
 TEST_P (AiksTest, DrawOpacityPeephole)
 
 TEST_P (AiksTest, CanRenderGroupOpacity)
 
 TEST_P (AiksTest, CanRenderGroupOpacityToSavelayer)
 
 TEST_P (AiksTest, RotateColorFilteredPath)
 
 TEST_P (AiksTest, CanRenderStrokes)
 
 TEST_P (AiksTest, CanRenderCurvedStrokes)
 
 TEST_P (AiksTest, CanRenderThickCurvedStrokes)
 
 TEST_P (AiksTest, CanRenderThinCurvedStrokes)
 
 TEST_P (AiksTest, CanRenderStrokePathThatEndsAtSharpTurn)
 
 TEST_P (AiksTest, CanRenderStrokePathWithCubicLine)
 
 TEST_P (AiksTest, CanRenderQuadraticStrokeWithInstantTurn)
 
 TEST_P (AiksTest, CanRenderDifferencePaths)
 
 TEST_P (AiksTest, CanDrawAnOpenPath)
 
 TEST_P (AiksTest, CanDrawAnOpenPathThatIsntARect)
 
 TEST_P (AiksTest, SolidStrokesRenderCorrectly)
 
 TEST_P (AiksTest, DrawLinesRenderCorrectly)
 
 TEST_P (AiksTest, DrawRectStrokesRenderCorrectly)
 
 TEST_P (AiksTest, DrawRectStrokesWithBevelJoinRenderCorrectly)
 
 TEST_P (AiksTest, CanDrawMultiContourConvexPath)
 
 TEST_P (AiksTest, ArcWithZeroSweepAndBlur)
 
 TEST_P (AiksTest, CanRenderClips)
 
 TEST_P (AiksTest, CanRenderOverlappingMultiContourPath)
 
 TEST_P (AiksTest, CanRenderClippedRuntimeEffects)
 
 TEST_P (AiksTest, DrawPaintTransformsBounds)
 
bool RenderTextInCanvasSkia (const std::shared_ptr< Context > &context, DisplayListBuilder &canvas, const std::string &text, const std::string_view &font_fixture, const TextRenderOptions &options={})
 
bool RenderTextInCanvasSTB (const std::shared_ptr< Context > &context, DisplayListBuilder &canvas, const std::string &text, const std::string &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, CanRenderTextFrameSTB)
 
 TEST_P (AiksTest, TextFrameSubpixelAlignment)
 
 TEST_P (AiksTest, CanRenderItalicizedText)
 
 TEST_P (AiksTest, CanRenderEmojiTextFrame)
 
 TEST_P (AiksTest, CanRenderEmojiTextFrameWithBlur)
 
 TEST_P (AiksTest, CanRenderEmojiTextFrameWithAlpha)
 
 TEST_P (AiksTest, CanRenderTextInSaveLayer)
 
 TEST_P (AiksTest, CanRenderTextOutsideBoundaries)
 
 TEST_P (AiksTest, TextRotated)
 
 TEST_P (AiksTest, DrawScaledTextWithPerspectiveNoSaveLayer)
 
 TEST_P (AiksTest, DrawScaledTextWithPerspectiveSaveLayer)
 
 TEST_P (AiksTest, CanRenderTextWithLargePerspectiveTransform)
 
 TEST_P (AiksTest, CanRenderTextWithPerspectiveTransformInSublist)
 
 TEST_P (AiksTest, TextForegroundShaderWithTransform)
 
 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, 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)
 
 TEST_P (AiksTest, TransformMultipliesCorrectly)
 
 TEST_P (AiksTest, CanvasCanPushPopCTM)
 
 TEST_P (AiksTest, CanvasCTMCanBeUpdated)
 
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_P (EntityTest, ClipContentsOptimizesFullScreenIntersectClips)
 
 INSTANTIATE_PLAYGROUND_SUITE (BlendFilterContentsTest)
 
 TEST_P (BlendFilterContentsTest, AdvancedBlendColorAlignsColorTo4)
 
 INSTANTIATE_PLAYGROUND_SUITE (GaussianBlurFilterContentsTest)
 
 TEST (GaussianBlurFilterContentsTest, Create)
 
 TEST (GaussianBlurFilterContentsTest, CoverageEmpty)
 
 TEST (GaussianBlurFilterContentsTest, CoverageSimple)
 
 TEST (GaussianBlurFilterContentsTest, CoverageWithSigma)
 
 TEST_P (GaussianBlurFilterContentsTest, CoverageWithTexture)
 
 TEST_P (GaussianBlurFilterContentsTest, CoverageWithEffectTransform)
 
 TEST (GaussianBlurFilterContentsTest, FilterSourceCoverage)
 
 TEST (GaussianBlurFilterContentsTest, CalculateSigmaValues)
 
 TEST_P (GaussianBlurFilterContentsTest, RenderCoverageMatchesGetCoverage)
 
 TEST_P (GaussianBlurFilterContentsTest, RenderCoverageMatchesGetCoverageTranslate)
 
 TEST_P (GaussianBlurFilterContentsTest, RenderCoverageMatchesGetCoverageRotated)
 
 TEST_P (GaussianBlurFilterContentsTest, CalculateUVsSimple)
 
 TEST_P (GaussianBlurFilterContentsTest, TextureContentsWithDestinationRect)
 
 TEST_P (GaussianBlurFilterContentsTest, TextureContentsWithDestinationRectScaled)
 
 TEST_P (GaussianBlurFilterContentsTest, TextureContentsWithEffectTransform)
 
 TEST (GaussianBlurFilterContentsTest, CalculateSigmaForBlurRadius)
 
 TEST (GaussianBlurFilterContentsTest, Coefficients)
 
 TEST (GaussianBlurFilterContentsTest, LerpHackKernelSamplesSimple)
 
 TEST (GaussianBlurFilterContentsTest, LerpHackKernelSamplesComplex)
 
 TEST (GaussianBlurFilterContentsTest, ChopHugeBlurs)
 
 TEST (FilterInputTest, CanSetLocalTransformForTexture)
 
 TEST (FilterInputTest, IsLeaf)
 
 TEST (FilterInputTest, SetCoverageInputs)
 
 INSTANTIATE_PLAYGROUND_SUITE (MatrixFilterContentsTest)
 
 TEST (MatrixFilterContentsTest, Create)
 
 TEST (MatrixFilterContentsTest, CoverageEmpty)
 
 TEST (MatrixFilterContentsTest, CoverageSimple)
 
 TEST (MatrixFilterContentsTest, Coverage2x)
 
 TEST (MatrixFilterContentsTest, Coverage2xEffect)
 
 TEST_P (MatrixFilterContentsTest, RenderCoverageMatchesGetCoverageIdentity)
 
 TEST_P (MatrixFilterContentsTest, RenderCoverageMatchesGetCoverageTranslate)
 
 TEST_P (MatrixFilterContentsTest, RenderCoverageMatchesGetCoverageClippedSubpassTranslate)
 
 TEST_P (MatrixFilterContentsTest, RenderCoverageMatchesGetCoverageScale)
 
 TEST_P (MatrixFilterContentsTest, RenderCoverageMatchesGetCoverageClippedSubpassScale)
 
 TEST_P (MatrixFilterContentsTest, RenderCoverageMatchesGetCoverageSubpassScale)
 
 INSTANTIATE_PLAYGROUND_SUITE (HostBufferTest)
 
 TEST_P (HostBufferTest, CanEmplace)
 
 TEST_P (HostBufferTest, CanEmplaceWithAlignment)
 
 TEST_P (HostBufferTest, HostBufferInitialState)
 
 TEST_P (HostBufferTest, ResetIncrementsFrameCounter)
 
 TEST_P (HostBufferTest, EmplacingLargerThanBlockSizeCreatesOneOffBufferCallback)
 
 TEST_P (HostBufferTest, EmplacingLargerThanBlockSizeCreatesOneOffBuffer)
 
 TEST_P (HostBufferTest, UnusedBuffersAreDiscardedWhenResetting)
 
 TEST_P (HostBufferTest, EmplaceWithProcIsAligned)
 
 TEST_P (HostBufferTest, EmplaceWithFailingAllocationDoesntCrash)
 
 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 (EntityPassClipStackTest, CanPushAndPopEntities)
 
 TEST (EntityPassClipStackTest, CanPopEntitiesSafely)
 
 TEST (EntityPassClipStackTest, CanAppendNoChange)
 
 TEST (EntityPassClipStackTest, AppendCoverageNoChange)
 
 TEST (EntityPassClipStackTest, AppendAndRestoreClipCoverage)
 
 TEST (EntityPassClipStackTest, AppendLargerClipCoverage)
 
 TEST (EntityPassClipStackTest, AppendLargerClipCoverageWithDifferenceOrNonSquare)
 
 TEST (EntityPassClipStackTest, AppendDecreasingSizeClipCoverage)
 
 TEST (EntityPassClipStackTest, AppendIncreasingSizeClipCoverage)
 
 TEST (EntityPassClipStackTest, UnbalancedRestore)
 
 TEST (EntityPassClipStackTest, ClipAndRestoreWithSubpasses)
 
 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, ClipContentsGetClipCoverageIsCorrect)
 
 TEST_P (EntityTest, RRectShadowTest)
 
 TEST_P (EntityTest, ColorMatrixFilterCoverageIsCorrect)
 
 TEST_P (EntityTest, ColorMatrixFilterEditable)
 
 TEST_P (EntityTest, LinearToSrgbFilterCoverageIsCorrect)
 
 TEST_P (EntityTest, LinearToSrgbFilter)
 
 TEST_P (EntityTest, SrgbToLinearFilterCoverageIsCorrect)
 
 TEST_P (EntityTest, SrgbToLinearFilter)
 
static Vector3 RGBToYUV (Vector3 rgb, YUVColorSpace yuv_color_space)
 
static std::vector< std::shared_ptr< Texture > > CreateTestYUVTextures (Context *context, YUVColorSpace yuv_color_space)
 
 TEST_P (EntityTest, YUVToRGBFilter)
 
 TEST_P (EntityTest, RuntimeEffect)
 
 TEST_P (EntityTest, RuntimeEffectCanSuccessfullyRender)
 
 TEST_P (EntityTest, RuntimeEffectCanPrecache)
 
 TEST_P (EntityTest, RuntimeEffectSetsRightSizeWhenUniformIsStruct)
 
 TEST_P (EntityTest, 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, 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 (EntityGeometryTest, RectGeometryCoversArea)
 
 TEST (EntityGeometryTest, FillPathGeometryCoversArea)
 
 TEST (EntityGeometryTest, FillPathGeometryCoversAreaNoInnerRect)
 
 TEST (EntityGeometryTest, LineGeometryCoverage)
 
 TEST (EntityGeometryTest, RoundRectGeometryCoversArea)
 
 TEST (EntityGeometryTest, GeometryResultHasReasonableDefaults)
 
 TEST (EntityGeometryTest, AlphaCoverageStrokePaths)
 
 TEST_P (RenderTargetCacheTest, CachesUsedTexturesAcrossFrames)
 
 TEST_P (RenderTargetCacheTest, DoesNotPersistFailedAllocations)
 
 TEST_P (RenderTargetCacheTest, CachedTextureGetsNewAttachmentConfig)
 
 TEST_P (RenderTargetCacheTest, CreateWithEmptySize)
 
 TEST (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 (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, 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, IsAligned2D)
 
 TEST (MatrixTest, IsAligned)
 
 TEST (MatrixTest, TransformHomogenous)
 
 TEST (MatrixTest, GetMaxBasisXYNegativeScale)
 
 TEST (MatrixTest, GetMaxBasisXYWithLargeAndSmallScalingFactor)
 
 TEST (MatrixTest, GetMaxBasisXYWithLargeAndSmallScalingFactorNonScaleTranslate)
 
 TEST (MatrixTest, TranslateWithPerspective)
 
 TEST (PathTest, CubicPathComponentPolylineDoesNotIncludePointOne)
 
 TEST (PathTest, EmptyPathWithContour)
 
 TEST (PathTest, PathCreatePolyLineDoesNotDuplicatePoints)
 
 TEST (PathTest, PathBuilderSetsCorrectContourPropertiesForAddCommands)
 
 TEST (PathTest, PathCreatePolylineGeneratesCorrectContourData)
 
 TEST (PathTest, PolylineGetContourPointBoundsReturnsCorrectRanges)
 
 TEST (PathTest, PathAddRectPolylineHasCorrectContourData)
 
 TEST (PathTest, PathPolylineDuplicatesAreRemovedForSameContour)
 
 TEST (PathTest, PolylineBufferReuse)
 
 TEST (PathTest, PolylineFailsWithNullptrBuffer)
 
 TEST (PathTest, PathShifting)
 
 TEST (PathTest, PathBuilderWillComputeBounds)
 
 TEST (PathTest, PathHorizontalLine)
 
 TEST (PathTest, PathVerticalLine)
 
 TEST (PathTest, QuadradicPath)
 
 TEST (PathTest, CubicPath)
 
 TEST (PathTest, BoundingBoxCubic)
 
 TEST (PathTest, BoundingBoxOfCompositePathIsCorrect)
 
 TEST (PathTest, ExtremaOfCubicPathComponentIsCorrect)
 
 TEST (PathTest, PathGetBoundingBoxForCubicWithNoDerivativeRootsIsCorrect)
 
 TEST (PathTest, EmptyPath)
 
 TEST (PathTest, SimplePath)
 
 TEST (PathTest, RepeatCloseDoesNotAddNewLines)
 
 TEST (PathTest, CloseAfterMoveDoesNotAddNewLines)
 
 TEST (PathTest, CloseAtOriginDoesNotAddNewLineSegment)
 
 TEST (PathTest, CanBeCloned)
 
 TEST (PathTest, PathBuilderDoesNotMutateCopiedPaths)
 
 TEST (RectTest, RectEmptyDeclaration)
 
 TEST (RectTest, IRectEmptyDeclaration)
 
 TEST (RectTest, RectDefaultConstructor)
 
 TEST (RectTest, IRectDefaultConstructor)
 
 TEST (RectTest, RectSimpleLTRB)
 
 TEST (RectTest, IRectSimpleLTRB)
 
 TEST (RectTest, RectSimpleXYWH)
 
 TEST (RectTest, IRectSimpleXYWH)
 
 TEST (RectTest, RectSimpleWH)
 
 TEST (RectTest, IRectSimpleWH)
 
 TEST (RectTest, RectOverflowXYWH)
 
 TEST (RectTest, IRectOverflowXYWH)
 
 TEST (RectTest, RectOverflowLTRB)
 
 TEST (RectTest, IRectOverflowLTRB)
 
 TEST (RectTest, RectMakeSize)
 
 TEST (RectTest, RectMakeMaximum)
 
 TEST (RectTest, IRectMakeMaximum)
 
 TEST (RectTest, RectFromRect)
 
 TEST (RectTest, IRectFromIRect)
 
 TEST (RectTest, RectCopy)
 
 TEST (RectTest, IRectCopy)
 
 TEST (RectTest, RectOriginSizeXYWHGetters)
 
 TEST (RectTest, IRectOriginSizeXYWHGetters)
 
 TEST (RectTest, RectRoundOutEmpty)
 
 TEST (RectTest, RectRoundOutSimple)
 
 TEST (RectTest, RectRoundOutToIRectHuge)
 
 TEST (RectTest, RectDoesNotIntersectEmpty)
 
 TEST (RectTest, IRectDoesNotIntersectEmpty)
 
 TEST (RectTest, EmptyRectDoesNotIntersect)
 
 TEST (RectTest, EmptyIRectDoesNotIntersect)
 
 TEST (RectTest, RectScale)
 
 TEST (RectTest, IRectScale)
 
 TEST (RectTest, RectArea)
 
 TEST (RectTest, IRectArea)
 
 TEST (RectTest, RectGetNormalizingTransform)
 
 TEST (RectTest, IRectGetNormalizingTransform)
 
 TEST (RectTest, RectXYWHIsEmpty)
 
 TEST (RectTest, IRectXYWHIsEmpty)
 
 TEST (RectTest, MakePointBoundsQuad)
 
 TEST (RectTest, IsSquare)
 
 TEST (RectTest, GetCenter)
 
 TEST (RectTest, RectExpand)
 
 TEST (RectTest, IRectExpand)
 
 TEST (RectTest, ContainsFloatingPoint)
 
template<typename R >
static constexpr R flip_lr (R rect)
 
template<typename R >
static constexpr R flip_tb (R rect)
 
template<typename R >
static constexpr R flip_lrtb (R rect)
 
static constexpr Rect swap_nan (const Rect &rect, int index)
 
static constexpr Point swap_nan (const Point &point, int index)
 
 TEST (RectTest, RectUnion)
 
 TEST (RectTest, OptRectUnion)
 
 TEST (RectTest, IRectUnion)
 
 TEST (RectTest, OptIRectUnion)
 
 TEST (RectTest, RectIntersection)
 
 TEST (RectTest, OptRectIntersection)
 
 TEST (RectTest, IRectIntersection)
 
 TEST (RectTest, OptIRectIntersection)
 
 TEST (RectTest, RectIntersectsWithRect)
 
 TEST (RectTest, IRectIntersectsWithRect)
 
 TEST (RectTest, RectContainsPoint)
 
 TEST (RectTest, IRectContainsIPoint)
 
 TEST (RectTest, RectContainsInclusivePoint)
 
 TEST (RectTest, IRectContainsInclusiveIPoint)
 
 TEST (RectTest, RectContainsRect)
 
 TEST (RectTest, IRectContainsIRect)
 
 TEST (RectTest, RectCutOut)
 
 TEST (RectTest, IRectCutOut)
 
 TEST (RectTest, RectGetPoints)
 
 TEST (RectTest, RectShift)
 
 TEST (RectTest, RectGetTransformedPoints)
 
 TEST (RectTest, RectMakePointBounds)
 
 TEST (RectTest, RectGetPositive)
 
 TEST (RectTest, RectDirections)
 
 TEST (RectTest, RectProject)
 
 TEST (RectTest, RectRoundOut)
 
 TEST (RectTest, IRectRoundOut)
 
 TEST (RectTest, RectRound)
 
 TEST (RectTest, IRectRound)
 
 TEST (RectTest, TransformAndClipBounds)
 
 TEST (SaturatedMath, ExplicitAddOfSignedInts)
 
 TEST (SaturatedMath, ImplicitAddOfSignedInts)
 
 TEST (SaturatedMath, ExplicitAddOfFloatingPoint)
 
 TEST (SaturatedMath, ImplicitAddOfFloatingPoint)
 
 TEST (SaturatedMath, ExplicitSubOfSignedInts)
 
 TEST (SaturatedMath, ImplicitSubOfSignedInts)
 
 TEST (SaturatedMath, ExplicitSubOfFloatingPoint)
 
 TEST (SaturatedMath, ImplicitSubOfFloatingPoint)
 
 TEST (SaturatedMath, ExplicitAverageScalarOfSignedInts)
 
 TEST (SaturatedMath, ImplicitAverageScalarOfSignedInts)
 
 TEST (SaturatedMath, ExplicitAverageScalarOfFloatingPoint)
 
 TEST (SaturatedMath, ImplicitAverageScalarOfFloatingPoint)
 
 TEST (SaturatedMath, CastingFiniteDoubleToFloatStaysFinite)
 
 TEST (SaturatedMath, CastingInfiniteDoubleToFloatStaysInfinite)
 
 TEST (SaturatedMath, CastingNaNDoubleToFloatStaysNaN)
 
 TEST (SaturatedMath, CastingLargeScalarToSignedIntProducesLimit)
 
 TEST (SaturatedMath, CastingInfiniteScalarToSignedIntProducesLimit)
 
 TEST (SaturatedMath, CastingNaNScalarToSignedIntProducesZero)
 
 TEST (SizeTest, SizeIsEmpty)
 
 TEST (SizeTest, ISizeIsEmpty)
 
 TEST (SizeTest, IsSquare)
 
 TEST (SizeTest, MaxDimension)
 
 TEST (SizeTest, NegationOperator)
 
 TEST (TrigTest, TrigAngles)
 
 TEST (TrigTest, MultiplyByScalarRadius)
 
 TEST_F (GoldenTests, ConicalGradient)
 
 INSTANTIATE_METAL_PLAYGROUND_SUITE (AllocatorMTLTest)
 
 TEST_P (AllocatorMTLTest, DebugTraceMemoryStatistics)
 
 TEST (TextureMTL, CreateFromDrawable)
 
 TEST (AllocatorVKTest, ToVKImageUsageFlags)
 
 TEST (AllocatorVKTest, MemoryTypeSelectionSingleHeap)
 
 TEST (AllocatorVKTest, MemoryTypeSelectionTwoHeap)
 
 TEST (CommandEncoderVKTest, DeleteEncoderAfterThreadDies)
 
 TEST (CommandEncoderVKTest, CleanupAfterSubmit)
 
 TEST (CommandPoolRecyclerVKTest, GetsACommandPoolPerThread)
 
 TEST (CommandPoolRecyclerVKTest, GetsTheSameCommandPoolOnSameThread)
 
 TEST (CommandPoolRecyclerVKTest, ReclaimMakesCommandPoolAvailable)
 
 TEST (CommandPoolRecyclerVKTest, CommandBuffersAreRecycled)
 
 TEST (ContextVKTest, CommonHardwareConcurrencyConfigurations)
 
 TEST (ContextVKTest, DeletesCommandPools)
 
 TEST (ContextVKTest, DeletesCommandPoolsOnAllThreads)
 
 TEST (ContextVKTest, 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 (DescriptorPoolRecyclerVKTest, GetDescriptorPoolRecyclerCreatesNewPools)
 
 TEST (DescriptorPoolRecyclerVKTest, ReclaimMakesDescriptorPoolAvailable)
 
 TEST (DescriptorPoolRecyclerVKTest, ReclaimDropsDescriptorPoolIfSizeIsExceeded)
 
 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)
 
 TEST (DriverInfoVKTest, DriverParsingMali)
 
 TEST (DriverInfoVKTest, DriverParsingArm)
 
 TEST (DriverInfoVKTest, DisabledDevices)
 
 TEST (DriverInfoVKTest, EnabledDevicesMali)
 
 TEST (DriverInfoVKTest, EnabledDevicesAdreno)
 
 TEST (FenceWaiterVKTest, IgnoresNullFence)
 
 TEST (FenceWaiterVKTest, IgnoresNullCallback)
 
 TEST (FenceWaiterVKTest, ExecutesFenceCallback)
 
 TEST (FenceWaiterVKTest, ExecutesFenceCallbackX2)
 
 TEST (FenceWaiterVKTest, ExecutesNewFenceThenOldFence)
 
 TEST (FenceWaiterVKTest, AddFenceDoesNothingIfTerminating)
 
 TEST (FenceWaiterVKTest, InProgressFencesStillWaitIfTerminated)
 
 TEST (PipelineCacheDataVKTest, CanTestHeaderCompatibility)
 
 TEST (PipelineCacheDataVKTest, CanCreateFromDeviceProperties)
 
 TEST_P (PipelineCacheDataVKPlaygroundTest, CanPersistAndRetrievePipelineCache)
 
 TEST_P (PipelineCacheDataVKPlaygroundTest, IntegrityChecksArePerformedOnPersistedData)
 
 TEST (RenderPassBuilder, CreatesRenderPassWithNoDepthStencil)
 
 TEST (RenderPassBuilder, CreatesRenderPassWithCombinedDepthStencil)
 
 TEST (RenderPassBuilder, CreatesRenderPassWithOnlyStencil)
 
 TEST (RenderPassBuilder, CreatesMSAAResolveWithCorrectStore)
 
 TEST_P (RendererTest, CachesRenderPassAndFramebuffer)
 
 TEST (ResourceManagerVKTest, CreatesANewInstance)
 
 TEST (ResourceManagerVKTest, ReclaimMovesAResourceAndDestroysIt)
 
 TEST (ResourceManagerVKTest, TerminatesWhenOutOfScope)
 
 TEST (ResourceManagerVKTest, IsThreadSafe)
 
 INSTANTIATE_PLAYGROUND_SUITE (BlitPassTest)
 
 TEST_P (BlitPassTest, BlitAcrossDifferentPixelFormatsFails)
 
 TEST_P (BlitPassTest, BlitAcrossDifferentSampleCountsFails)
 
 TEST_P (BlitPassTest, BlitPassesForMatchingFormats)
 
 TEST_P (BlitPassTest, ChecksInvalidSliceParameters)
 
 TEST_P (BlitPassTest, CanBlitSmallRegionToUninitializedTexture)
 
 TEST_P (BlitPassTest, CanResizeTextures)
 
 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, UniformBindFailsForInvalidHostBufferOffset)
 
 TEST_P (RendererDartTest, CanCreateRenderPassAndSubmit)
 
 TEST_P (RendererTest, CanCreateBoxPrimitive)
 
 TEST_P (RendererTest, BabysFirstTriangle)
 
 TEST_P (RendererTest, CanRenderPerspectiveCube)
 
 TEST_P (RendererTest, CanRenderMultiplePrimitives)
 
 TEST_P (RendererTest, CanRenderToTexture)
 
 TEST_P (RendererTest, CanRenderInstanced)
 
 TEST_P (RendererTest, CanBlitTextureToTexture)
 
 TEST_P (RendererTest, CanBlitTextureToBuffer)
 
 TEST_P (RendererTest, CanGenerateMipmaps)
 
 TEST_P (RendererTest, TheImpeller)
 
 TEST_P (RendererTest, Planet)
 
 TEST_P (RendererTest, ArrayUniforms)
 
 TEST_P (RendererTest, InactiveUniforms)
 
 TEST_P (RendererTest, DefaultIndexSize)
 
 TEST_P (RendererTest, DefaultIndexBehavior)
 
 TEST_P (RendererTest, VertexBufferBuilder)
 
static const CompareFunctionUIDataCompareFunctionUI ()
 
 TEST_P (RendererTest, StencilMask)
 
 TEST_P (RendererTest, CanLookupRenderTargetProperties)
 
 TEST_P (RendererTest, RenderTargetCreateOffscreenMSAASetsDefaultDepthStencilFormat)
 
template<class VertexShader , class FragmentShader >
std::shared_ptr< Pipeline< PipelineDescriptor > > CreateDefaultPipeline (const std::shared_ptr< Context > &context)
 
 TEST_P (RendererTest, CanSepiaToneWithSubpasses)
 
 TEST_P (RendererTest, CanSepiaToneThenSwizzleWithSubpasses)
 
 INSTANTIATE_PLAYGROUND_SUITE (RuntimeStageTest)
 
 TEST_P (RuntimeStageTest, CanReadValidBlob)
 
 TEST_P (RuntimeStageTest, CanRejectInvalidBlob)
 
 TEST_P (RuntimeStageTest, CanReadUniforms)
 
 TEST_P (RuntimeStageTest, CanReadUniformsSamplerBeforeUBO)
 
 TEST_P (RuntimeStageTest, CanReadUniformsSamplerAfterUBO)
 
 TEST_P (RuntimeStageTest, CanRegisterStage)
 
 TEST_P (RuntimeStageTest, CanCreatePipelineFromRuntimeStage)
 
 TEST_P (RuntimeStageTest, ContainsExpectedShaderTypes)
 
static std::shared_ptr< fml::Mapping > CreateMappingFromString (std::string p_string)
 
const std::string CreateStringFromMapping (const fml::Mapping &mapping)
 
 TEST (ShaderArchiveTest, CanReadAndWriteBlobs)
 
 TEST (TessellatorTest, TessellatorBuilderReturnsCorrectResultStatus)
 
 TEST (TessellatorTest, TessellateConvex)
 
 TEST (TessellatorTest, TessellateConvexUnclosedPath)
 
 TEST (TessellatorTest, CircleVertexCounts)
 
 TEST (TessellatorTest, FilledCircleTessellationVertices)
 
 TEST (TessellatorTest, StrokedCircleTessellationVertices)
 
 TEST (TessellatorTest, RoundCapLineTessellationVertices)
 
 TEST (TessellatorTest, FilledEllipseTessellationVertices)
 
 TEST (TessellatorTest, FilledRoundRectTessellationVertices)
 
 TEST (TessellatorTest, EarlyReturnEmptyConvexShape)
 
 TEST (TessellatorTest, ChecksConcurrentPolylineUsage)
 
static std::shared_ptr< GlyphAtlasCreateGlyphAtlas (Context &context, const TypographerContext *typographer_context, HostBuffer &host_buffer, GlyphAtlas::Type type, Scalar scale, const std::shared_ptr< GlyphAtlasContext > &atlas_context, const TextFrame &frame)
 
static std::shared_ptr< GlyphAtlasCreateGlyphAtlas (Context &context, const TypographerContext *typographer_context, HostBuffer &host_buffer, GlyphAtlas::Type type, Scalar scale, const std::shared_ptr< GlyphAtlasContext > &atlas_context, const std::vector< std::shared_ptr< TextFrame >> &frames, const std::vector< GlyphProperties > &properties)
 
 TEST_P (TypographerTest, CanConvertTextBlob)
 
 TEST_P (TypographerTest, CanCreateRenderContext)
 
 TEST_P (TypographerTest, CanCreateGlyphAtlas)
 
 TEST_P (TypographerTest, LazyAtlasTracksColor)
 
 TEST_P (TypographerTest, GlyphAtlasWithOddUniqueGlyphSize)
 
 TEST_P (TypographerTest, GlyphAtlasIsRecycledIfUnchanged)
 
 TEST_P (TypographerTest, GlyphAtlasWithLotsOfdUniqueGlyphSize)
 
 TEST_P (TypographerTest, GlyphAtlasTextureIsRecycledIfUnchanged)
 
 TEST_P (TypographerTest, GlyphColorIsPartOfCacheKey)
 
 TEST_P (TypographerTest, GlyphColorIsIgnoredForNonEmojiFonts)
 
 TEST_P (TypographerTest, RectanglePackerAddsNonoverlapingRectangles)
 
 TEST (TypographerTest, RectanglePackerFillsRows)
 
 TEST_P (TypographerTest, GlyphAtlasTextureWillGrowTilMaxTextureSize)
 

Variables

static const std::map< std::string, MaskBlurTestConfigkPaintVariations
 
static constexpr std::string_view kFontFixture
 
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 19 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.

◆ 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 501 of file aiks_dl_blend_unittests.cc.

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

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

◆ CanRenderConicalGradientWithDithering()

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

Definition at line 167 of file aiks_dl_gradient_unittests.cc.

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

References impeller::Playground::GetContentScale(), impeller::AiksPlayground::OpenPlaygroundHere(), 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().

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

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

References data.

Referenced by TEST_P().

◆ CreateDefaultPipeline()

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

Definition at line 1376 of file renderer_unittests.cc.

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

References impeller::kCount4.

◆ CreateGlyphAtlas() [1/2]

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

Definition at line 46 of file typographer_unittests.cc.

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

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

◆ CreateGlyphAtlas() [2/2]

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

Definition at line 32 of file typographer_unittests.cc.

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

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

Referenced by TEST_P().

◆ CreateMappingFromString()

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

Definition at line 15 of file shader_archive_unittests.cc.

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

Referenced by TEST().

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

Definition at line 13 of file canvas_unittests.cc.

15  {
16  RenderTarget render_target = context.GetRenderTargetCache()->CreateOffscreen(
17  *context.GetContext(), {1, 1}, 1);
18 
19  if (cull_rect.has_value()) {
20  return std::make_unique<Canvas>(context, render_target, false,
21  cull_rect.value());
22  }
23  return std::make_unique<Canvas>(context, render_target, false);
24 }

References impeller::ContentContext::GetContext(), and impeller::ContentContext::GetRenderTargetCache().

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

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

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({100, 0}, {100, 60}, line_paint);
92  builder.DrawLine({0, 30}, {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 1310 of file rect_unittests.cc.

1310  {
1311  return R::MakeLTRB(rect.GetRight(), rect.GetTop(), //
1312  rect.GetLeft(), rect.GetBottom());
1313 }

Referenced by flip_lrtb(), and TEST().

◆ flip_lrtb()

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

Definition at line 1322 of file rect_unittests.cc.

1322  {
1323  return flip_lr(flip_tb(rect));
1324 }

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

1316  {
1317  return R::MakeLTRB(rect.GetLeft(), rect.GetBottom(), //
1318  rect.GetRight(), rect.GetTop());
1319 }

Referenced by flip_lrtb(), and TEST().

◆ 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 }

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

◆ INSTANTIATE_PLAYGROUND_SUITE() [4/9]

impeller::testing::INSTANTIATE_PLAYGROUND_SUITE ( DisplayListTest  )

◆ INSTANTIATE_PLAYGROUND_SUITE() [5/9]

impeller::testing::INSTANTIATE_PLAYGROUND_SUITE ( GaussianBlurFilterContentsTest  )

◆ INSTANTIATE_PLAYGROUND_SUITE() [6/9]

impeller::testing::INSTANTIATE_PLAYGROUND_SUITE ( HostBufferTest  )

◆ INSTANTIATE_PLAYGROUND_SUITE() [7/9]

impeller::testing::INSTANTIATE_PLAYGROUND_SUITE ( MatrixFilterContentsTest  )

◆ INSTANTIATE_PLAYGROUND_SUITE() [8/9]

impeller::testing::INSTANTIATE_PLAYGROUND_SUITE ( RendererDartTest  )

◆ INSTANTIATE_PLAYGROUND_SUITE() [9/9]

impeller::testing::INSTANTIATE_PLAYGROUND_SUITE ( RuntimeStageTest  )

◆ INSTANTIATE_VULKAN_PLAYGROUND_SUITE()

impeller::testing::INSTANTIATE_VULKAN_PLAYGROUND_SUITE ( DriverInfoVKTest  )

◆ InstantiateTestShaderLibrary()

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

Definition at line 34 of file renderer_dart_unittests.cc.

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

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

◆ 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 403 of file aiks_dl_blur_unittests.cc.

405  {
406  DisplayListBuilder builder;
407  builder.Scale(test_context.GetContentScale().x,
408  test_context.GetContentScale().y);
409  builder.Scale(0.8f, 0.8f);
410  builder.Translate(50.f, 50.f);
411 
412  DlPaint draw_paint;
413  draw_paint.setColor(
414  DlColor::RGBA(Color::AntiqueWhite().red, Color::AntiqueWhite().green,
415  Color::AntiqueWhite().blue, Color::AntiqueWhite().alpha));
416  builder.DrawPaint(draw_paint);
417 
418  DlPaint paint;
419  paint.setMaskFilter(DlBlurMaskFilter::Make(config.style, config.sigma));
420  paint.setInvertColors(config.invert_colors);
421  paint.setImageFilter(config.image_filter);
422  paint.setBlendMode(config.blend_mode);
423 
424  const Scalar x = 50;
425  const Scalar radius = 20.0f;
426  const Scalar y_spacing = 100.0f;
427  Scalar alpha = config.alpha * 255;
428 
429  Scalar y = 50;
430  paint.setColor(DlColor::kCrimson().withAlpha(alpha));
431  builder.DrawRect(SkRect::MakeXYWH(x + 25 - radius / 2, y + radius / 2, //
432  radius, 60.0f - radius),
433  paint);
434 
435  y += y_spacing;
436  paint.setColor(DlColor::kBlue().withAlpha(alpha));
437  builder.DrawCircle({x + 25, y + 25}, radius, paint);
438 
439  y += y_spacing;
440  paint.setColor(DlColor::kGreen().withAlpha(alpha));
441  builder.DrawOval(SkRect::MakeXYWH(x + 25 - radius / 2, y + radius / 2, //
442  radius, 60.0f - radius),
443  paint);
444 
445  y += y_spacing;
446  paint.setColor(DlColor::kPurple().withAlpha(alpha));
447  SkRRect rrect =
448  SkRRect::MakeRectXY(SkRect::MakeXYWH(x, y, 60.0f, 60.0f), radius, radius);
449  builder.DrawRRect(rrect, paint);
450 
451  y += y_spacing;
452  paint.setColor(DlColor::kOrange().withAlpha(alpha));
453 
454  rrect =
455  SkRRect::MakeRectXY(SkRect::MakeXYWH(x, y, 60.0f, 60.0f), radius, 5.0);
456  builder.DrawRRect(rrect, paint);
457 
458  y += y_spacing;
459  paint.setColor(DlColor::kMaroon().withAlpha(alpha));
460 
461  {
462  SkPath path;
463  path.moveTo(x + 0, y + 60);
464  path.lineTo(x + 30, y + 0);
465  path.lineTo(x + 60, y + 60);
466  path.close();
467 
468  builder.DrawPath(path, paint);
469  }
470 
471  y += y_spacing;
472  paint.setColor(DlColor::kMaroon().withAlpha(alpha));
473  {
474  SkPath path;
475  path.addArc(SkRect::MakeXYWH(x + 5, y, 50, 50), 90, 180);
476  path.addArc(SkRect::MakeXYWH(x + 25, y, 50, 50), 90, 180);
477  path.close();
478  builder.DrawPath(path, paint);
479  }
480 
481  return builder.Build();
482 }

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, 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 41 of file aiks_dl_text_unittests.cc.

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

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

◆ RenderTextInCanvasSTB()

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

Definition at line 84 of file aiks_dl_text_unittests.cc.

88  {}) {
89  // Draw the baseline.
90  DlPaint paint;
91  paint.setColor(DlColor::kAqua().withAlpha(255 * 0.25));
92  canvas.DrawRect(SkRect::MakeXYWH(options.position.x() - 50,
93  options.position.y(), 900, 10),
94  paint);
95 
96  // Mark the point at which the text is drawn.
97  paint.setColor(DlColor::kRed().withAlpha(255 * 0.25));
98  canvas.DrawCircle(options.position, 5.0, paint);
99 
100  // Construct the text blob.
101  auto mapping = flutter::testing::OpenFixtureAsMapping(font_fixture.c_str());
102  if (!mapping) {
103  return false;
104  }
105  auto typeface_stb = std::make_shared<TypefaceSTB>(std::move(mapping));
106 
107  auto frame = MakeTextFrameSTB(
108  typeface_stb, Font::Metrics{.point_size = options.font_size}, text);
109 
110  DlPaint text_paint;
111  text_paint.setColor(options.color);
112 
113  canvas.DrawTextFrame(frame, options.position.x(), options.position.y(),
114  text_paint);
115  return true;
116 }

Referenced by TEST_P().

◆ RGBToYUV()

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

Definition at line 1642 of file entity_unittests.cc.

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

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

1336  {
1337  Scalar nan = std::numeric_limits<Scalar>::quiet_NaN();
1338  FML_DCHECK(index >= 0 && index <= 3);
1339  Scalar x = ((index & (1 << 0)) != 0) ? nan : point.x;
1340  Scalar y = ((index & (1 << 1)) != 0) ? nan : point.y;
1341  return Point(x, y);
1342 }

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

◆ swap_nan() [2/2]

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

Definition at line 1326 of file rect_unittests.cc.

1326  {
1327  Scalar nan = std::numeric_limits<Scalar>::quiet_NaN();
1328  FML_DCHECK(index >= 0 && index <= 15);
1329  Scalar l = ((index & (1 << 0)) != 0) ? nan : rect.GetLeft();
1330  Scalar t = ((index & (1 << 1)) != 0) ? nan : rect.GetTop();
1331  Scalar r = ((index & (1 << 2)) != 0) ? nan : rect.GetRight();
1332  Scalar b = ((index & (1 << 3)) != 0) ? nan : rect.GetBottom();
1333  return Rect::MakeLTRB(l, t, r, b);
1334 }

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

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 }

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

◆ TEST() [2/389]

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

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

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 }

◆ TEST() [5/389]

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

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

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

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

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

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

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

Definition at line 16 of file allocator_unittests.cc.

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

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

◆ TEST() [12/389]

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

Definition at line 36 of file allocator_vk_unittests.cc.

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

References impeller::AllocatorVK::FindMemoryTypeIndex().

◆ TEST() [13/389]

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

Definition at line 51 of file allocator_vk_unittests.cc.

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

References impeller::AllocatorVK::FindMemoryTypeIndex().

◆ TEST() [14/389]

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

Definition at line 17 of file allocator_vk_unittests.cc.

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

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

◆ TEST() [15/389]

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 }

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

◆ TEST() [16/389]

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

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

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

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

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

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

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

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

Definition at line 214 of file context_vk_unittests.cc.

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

◆ TEST() [24/389]

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

Definition at line 183 of file context_vk_unittests.cc.

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

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

◆ TEST() [25/389]

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

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

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

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

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

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

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

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

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 }

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

◆ TEST() [34/389]

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

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

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

Definition at line 151 of file context_vk_unittests.cc.

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

References impeller::CapabilitiesVK::AreValidationsEnabled().

◆ TEST() [37/389]

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

Definition at line 165 of file context_vk_unittests.cc.

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

References impeller::CapabilitiesVK::AreValidationsEnabled().

◆ TEST() [38/389]

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

Definition at line 16 of file context_vk_unittests.cc.

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

References impeller::ContextVK::ChooseThreadCountForWorkers().

◆ TEST() [39/389]

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

Definition at line 94 of file context_vk_unittests.cc.

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

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

◆ TEST() [40/389]

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

Definition at line 135 of file context_vk_unittests.cc.

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

References impeller::PipelineDescriptor::SetVertexDescriptor().

◆ TEST() [41/389]

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

Definition at line 29 of file context_vk_unittests.cc.

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

◆ TEST() [42/389]

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

Definition at line 44 of file context_vk_unittests.cc.

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

◆ TEST() [43/389]

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

Definition at line 113 of file context_vk_unittests.cc.

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

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

◆ TEST() [44/389]

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

Definition at line 244 of file context_vk_unittests.cc.

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

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

◆ TEST() [45/389]

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

Definition at line 255 of file context_vk_unittests.cc.

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

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

◆ TEST() [46/389]

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

Definition at line 75 of file context_vk_unittests.cc.

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

◆ TEST() [47/389]

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

Definition at line 233 of file context_vk_unittests.cc.

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

References impeller::kR8G8B8A8UNormInt.

◆ TEST() [48/389]

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

Definition at line 15 of file descriptor_pool_vk_unittests.cc.

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

◆ TEST() [49/389]

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

Definition at line 65 of file descriptor_pool_vk_unittests.cc.

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

◆ TEST() [50/389]

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

Definition at line 27 of file descriptor_pool_vk_unittests.cc.

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

◆ TEST() [51/389]

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

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

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

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

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

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

Definition at line 81 of file driver_info_vk_unittests.cc.

81  {
82  EXPECT_TRUE(IsBadVersionTest("Adreno (TM) 630"));
83  EXPECT_TRUE(IsBadVersionTest("Adreno (TM) 620"));
84  EXPECT_TRUE(IsBadVersionTest("Adreno (TM) 610"));
85  EXPECT_TRUE(IsBadVersionTest("Adreno (TM) 530"));
86  EXPECT_TRUE(IsBadVersionTest("Adreno (TM) 512"));
87  EXPECT_TRUE(IsBadVersionTest("Adreno (TM) 509"));
88  EXPECT_TRUE(IsBadVersionTest("Adreno (TM) 508"));
89  EXPECT_TRUE(IsBadVersionTest("Adreno (TM) 506"));
90  EXPECT_TRUE(IsBadVersionTest("Adreno (TM) 505"));
91  EXPECT_TRUE(IsBadVersionTest("Adreno (TM) 504"));
92  EXPECT_TRUE(IsBadVersionTest("Adreno (TM) 640"));
93 
94  EXPECT_FALSE(IsBadVersionTest("Adreno (TM) 650"));
95 }

References IsBadVersionTest().

◆ TEST() [57/389]

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

Definition at line 76 of file driver_info_vk_unittests.cc.

76  {
77  EXPECT_EQ(GetAdrenoVersion("Adreno (TM) 540"), AdrenoGPU::kAdreno540);
78  EXPECT_EQ(GetAdrenoVersion("Foo Bar"), AdrenoGPU::kUnknown);
79 }

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

◆ TEST() [58/389]

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

Definition at line 70 of file driver_info_vk_unittests.cc.

70  {
71  EXPECT_EQ(GetMaliVersion("Mali-G51-MORE STUFF"), MaliGPU::kG51);
72  EXPECT_EQ(GetMaliVersion("Mali-G51"), MaliGPU::kG51);
73  EXPECT_EQ(GetMaliVersion("Mali-111111"), MaliGPU::kUnknown);
74 }

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

◆ TEST() [59/389]

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

Definition at line 102 of file driver_info_vk_unittests.cc.

102  {
103  EXPECT_FALSE(IsBadVersionTest("Adreno (TM) 750"));
104  EXPECT_FALSE(IsBadVersionTest("Adreno (TM) 740"));
105  EXPECT_FALSE(IsBadVersionTest("Adreno (TM) 732"));
106  EXPECT_FALSE(IsBadVersionTest("Adreno (TM) 730"));
107  EXPECT_FALSE(IsBadVersionTest("Adreno (TM) 725"));
108  EXPECT_FALSE(IsBadVersionTest("Adreno (TM) 720"));
109  EXPECT_FALSE(IsBadVersionTest("Adreno (TM) 710"));
110  EXPECT_FALSE(IsBadVersionTest("Adreno (TM) 702"));
111 }

References IsBadVersionTest().

◆ TEST() [60/389]

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

Definition at line 97 of file driver_info_vk_unittests.cc.

97  {
98  EXPECT_FALSE(IsBadVersionTest("Mali-G52", /*qc=*/false));
99  EXPECT_FALSE(IsBadVersionTest("Mali-G54-MORE STUFF", /*qc=*/false));
100 }

References IsBadVersionTest().

◆ TEST() [61/389]

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 }

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

◆ TEST() [62/389]

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

Definition at line 78 of file geometry_unittests.cc.

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

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

◆ TEST() [63/389]

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

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

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

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

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

Definition at line 123 of file geometry_unittests.cc.

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

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

◆ TEST() [68/389]

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

Definition at line 92 of file entity_pass_unittests.cc.

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

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

◆ TEST() [69/389]

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

Definition at line 69 of file entity_pass_unittests.cc.

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

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

◆ TEST() [70/389]

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

Definition at line 197 of file entity_pass_unittests.cc.

197  {
198  EntityPassClipStack recorder =
199  EntityPassClipStack(Rect::MakeLTRB(0, 0, 100, 100));
200 
201  ASSERT_EQ(recorder.GetClipCoverageLayers().size(), 1u);
202 
203  // Push Clips that shrink in size. All should be applied.
204  Entity entity;
205 
206  for (auto i = 1; i < 20; i++) {
207  EntityPassClipStack::ClipStateResult result = recorder.ApplyClipState(
208  Contents::ClipCoverage{
209  .type = Contents::ClipCoverage::Type::kAppend,
210  .coverage = Rect::MakeLTRB(i, i, 100 - i, 100 - i),
211  },
212  entity, 0, Point(0, 0));
213  EXPECT_TRUE(result.should_render);
214  EXPECT_TRUE(result.clip_did_change);
215  EXPECT_EQ(recorder.CurrentClipCoverage(),
216  Rect::MakeLTRB(i, i, 100 - i, 100 - i));
217  }
218 }

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

◆ TEST() [71/389]

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

Definition at line 220 of file entity_pass_unittests.cc.

220  {
221  EntityPassClipStack recorder =
222  EntityPassClipStack(Rect::MakeLTRB(0, 0, 100, 100));
223 
224  ASSERT_EQ(recorder.GetClipCoverageLayers().size(), 1u);
225 
226  // Push Clips that grow in size. All should be skipped.
227  Entity entity;
228 
229  for (auto i = 1; i < 20; i++) {
230  EntityPassClipStack::ClipStateResult result = recorder.ApplyClipState(
231  Contents::ClipCoverage{
232  .type = Contents::ClipCoverage::Type::kAppend,
233  .coverage = Rect::MakeLTRB(0 - i, 0 - i, 100 + i, 100 + i),
234  },
235  entity, 0, Point(0, 0));
236  EXPECT_FALSE(result.should_render);
237  EXPECT_FALSE(result.clip_did_change);
238  EXPECT_EQ(recorder.CurrentClipCoverage(), Rect::MakeLTRB(0, 0, 100, 100));
239  }
240 }

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

◆ TEST() [72/389]

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

Definition at line 135 of file entity_pass_unittests.cc.

135  {
136  EntityPassClipStack recorder =
137  EntityPassClipStack(Rect::MakeLTRB(0, 0, 100, 100));
138 
139  ASSERT_EQ(recorder.GetClipCoverageLayers().size(), 1u);
140 
141  // Push a clip.
142  Entity entity;
143  EntityPassClipStack::ClipStateResult result = recorder.ApplyClipState(
144  Contents::ClipCoverage{
145  .type = Contents::ClipCoverage::Type::kAppend,
146  .coverage = Rect::MakeLTRB(50, 50, 55, 55),
147  },
148  entity, 0, Point(0, 0));
149  EXPECT_TRUE(result.should_render);
150  EXPECT_TRUE(result.clip_did_change);
151 
152  // Push a clip with larger coverage than the previous state.
153  result = recorder.ApplyClipState(
154  Contents::ClipCoverage{
155  .type = Contents::ClipCoverage::Type::kAppend,
156  .coverage = Rect::MakeLTRB(0, 0, 100, 100),
157  },
158  entity, 0, Point(0, 0));
159 
160  EXPECT_FALSE(result.should_render);
161  EXPECT_FALSE(result.clip_did_change);
162 }

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

◆ TEST() [73/389]

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

Definition at line 166 of file entity_pass_unittests.cc.

167  {
168  EntityPassClipStack recorder =
169  EntityPassClipStack(Rect::MakeLTRB(0, 0, 100, 100));
170 
171  ASSERT_EQ(recorder.GetClipCoverageLayers().size(), 1u);
172 
173  // Push a clip.
174  Entity entity;
175  EntityPassClipStack::ClipStateResult result = recorder.ApplyClipState(
176  Contents::ClipCoverage{
177  .type = Contents::ClipCoverage::Type::kAppend,
178  .coverage = Rect::MakeLTRB(50, 50, 55, 55),
179  },
180  entity, 0, Point(0, 0));
181  EXPECT_TRUE(result.should_render);
182  EXPECT_TRUE(result.clip_did_change);
183 
184  // Push a clip with larger coverage than the previous state.
185  result = recorder.ApplyClipState(
186  Contents::ClipCoverage{
187  .type = Contents::ClipCoverage::Type::kAppend,
188  .is_difference_or_non_square = true,
189  .coverage = Rect::MakeLTRB(0, 0, 100, 100),
190  },
191  entity, 0, Point(0, 0));
192 
193  EXPECT_TRUE(result.should_render);
194  EXPECT_TRUE(result.clip_did_change);
195 }

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

◆ TEST() [74/389]

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

Definition at line 57 of file entity_pass_unittests.cc.

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

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

◆ TEST() [75/389]

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

Definition at line 46 of file entity_pass_unittests.cc.

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

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

◆ TEST() [76/389]

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

Definition at line 16 of file entity_pass_unittests.cc.

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

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

◆ TEST() [77/389]

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

Definition at line 269 of file entity_pass_unittests.cc.

269  {
270  EntityPassClipStack recorder =
271  EntityPassClipStack(Rect::MakeLTRB(0, 0, 100, 100));
272 
273  ASSERT_EQ(recorder.GetClipCoverageLayers().size(), 1u);
274 
275  // Push a clip.
276  Entity entity;
277  {
278  EntityPassClipStack::ClipStateResult result = recorder.ApplyClipState(
279  Contents::ClipCoverage{
280  .type = Contents::ClipCoverage::Type::kAppend,
281  .coverage = Rect::MakeLTRB(50, 50, 55, 55),
282  },
283  entity, 0, Point(0, 0));
284  EXPECT_TRUE(result.should_render);
285  EXPECT_TRUE(result.clip_did_change);
286  }
287 
288  ASSERT_EQ(recorder.GetClipCoverageLayers().size(), 2u);
289  EXPECT_EQ(recorder.GetClipCoverageLayers()[1].coverage,
290  Rect::MakeLTRB(50, 50, 55, 55));
291  EXPECT_EQ(recorder.GetClipCoverageLayers()[1].clip_height, 1u);
292  EXPECT_EQ(recorder.GetReplayEntities().size(), 1u);
293 
294  // Begin a subpass.
295  recorder.PushSubpass(Rect::MakeLTRB(50, 50, 55, 55), 1);
296  ASSERT_EQ(recorder.GetClipCoverageLayers().size(), 1u);
297  EXPECT_EQ(recorder.GetClipCoverageLayers()[0].coverage,
298  Rect::MakeLTRB(50, 50, 55, 55));
299 
300  {
301  EntityPassClipStack::ClipStateResult result = recorder.ApplyClipState(
302  Contents::ClipCoverage{
303  .type = Contents::ClipCoverage::Type::kAppend,
304  .coverage = Rect::MakeLTRB(54, 54, 55, 55),
305  },
306  entity, 0, Point(0, 0));
307  EXPECT_TRUE(result.should_render);
308  EXPECT_TRUE(result.clip_did_change);
309  }
310 
311  EXPECT_EQ(recorder.GetClipCoverageLayers()[1].coverage,
312  Rect::MakeLTRB(54, 54, 55, 55));
313 
314  // End subpass.
315  recorder.PopSubpass();
316 
317  EXPECT_EQ(recorder.GetClipCoverageLayers()[1].coverage,
318  Rect::MakeLTRB(50, 50, 55, 55));
319 }

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

◆ TEST() [78/389]

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

Definition at line 242 of file entity_pass_unittests.cc.

242  {
243  EntityPassClipStack recorder =
244  EntityPassClipStack(Rect::MakeLTRB(0, 0, 100, 100));
245 
246  ASSERT_EQ(recorder.GetClipCoverageLayers().size(), 1u);
247 
248  // Restore the clip.
249  Entity entity;
250  auto restore_clip = std::make_shared<ClipRestoreContents>();
251  restore_clip->SetRestoreHeight(0);
252  entity.SetContents(std::move(restore_clip));
253  EntityPassClipStack::ClipStateResult result = recorder.ApplyClipState(
254  Contents::ClipCoverage{
255  .type = Contents::ClipCoverage::Type::kRestore,
256  .coverage = Rect::MakeLTRB(50, 50, 55, 55),
257  },
258  entity, 0, Point(0, 0));
259  EXPECT_FALSE(result.should_render);
260  EXPECT_FALSE(result.clip_did_change);
261 
262  ASSERT_EQ(recorder.GetClipCoverageLayers().size(), 1u);
263  EXPECT_EQ(recorder.GetClipCoverageLayers()[0].coverage,
264  Rect::MakeSize(Size::MakeWH(100, 100)));
265  EXPECT_EQ(recorder.GetClipCoverageLayers()[0].clip_height, 0u);
266  EXPECT_EQ(recorder.GetReplayEntities().size(), 0u);
267 }

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

◆ TEST() [79/389]

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

Definition at line 86 of file fence_waiter_vk_unittests.cc.

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

◆ TEST() [80/389]

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

Definition at line 28 of file fence_waiter_vk_unittests.cc.

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

◆ TEST() [81/389]

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

Definition at line 40 of file fence_waiter_vk_unittests.cc.

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

◆ TEST() [82/389]

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

Definition at line 57 of file fence_waiter_vk_unittests.cc.

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

◆ TEST() [83/389]

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

Definition at line 19 of file fence_waiter_vk_unittests.cc.

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

◆ TEST() [84/389]

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

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

Definition at line 103 of file fence_waiter_vk_unittests.cc.

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

◆ TEST() [86/389]

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

Definition at line 17 of file filter_input_unittests.cc.

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

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

◆ TEST() [87/389]

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

Definition at line 30 of file filter_input_unittests.cc.

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

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

◆ TEST() [88/389]

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

Definition at line 42 of file filter_input_unittests.cc.

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

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

◆ TEST() [89/389]

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

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

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 }

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

◆ TEST() [92/389]

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

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

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

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

Definition at line 145 of file gaussian_blur_filter_contents_unittests.cc.

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

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

◆ TEST() [96/389]

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

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

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

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 }

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

◆ TEST() [100/389]

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

Definition at line 1663 of file geometry_unittests.cc.

1663  {
1664  using BlendT = std::underlying_type_t<BlendMode>;
1665  for (BlendT i = 0; i <= static_cast<BlendT>(BlendMode::kLast); i++) {
1666  auto mode = static_cast<BlendMode>(i);
1667  auto result = BlendModeToString(mode);
1669  }
1670 }

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

◆ TEST() [101/389]

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

Definition at line 1672 of file geometry_unittests.cc.

1672  {
1673  {
1674  auto deg = Degrees{90.0};
1675  Radians rad = deg;
1676  ASSERT_FLOAT_EQ(rad.radians, kPiOver2);
1677  }
1678 }

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

◆ TEST() [102/389]

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 }

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

◆ TEST() [103/389]

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

Definition at line 580 of file geometry_unittests.cc.

580  {
581  ASSERT_EQ((Size{128, 128}.MipCount()), 7u);
582  ASSERT_EQ((Size{128, 256}.MipCount()), 8u);
583  ASSERT_EQ((Size{128, 130}.MipCount()), 8u);
584  ASSERT_EQ((Size{128, 257}.MipCount()), 9u);
585  ASSERT_EQ((Size{257, 128}.MipCount()), 9u);
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 }

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

◆ TEST() [104/389]

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

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

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

Definition at line 1230 of file geometry_unittests.cc.

1230  {
1231  {
1232  Vector3 p1(1, 2, 3);
1233  Vector3 p2 = p1 + Vector3(1, 2, 3);
1234  ASSERT_EQ(p2.x, 2u);
1235  ASSERT_EQ(p2.y, 4u);
1236  ASSERT_EQ(p2.z, 6u);
1237  }
1238 
1239  {
1240  Vector3 p1(3, 6, 9);
1241  Vector3 p2 = p1 - Vector3(1, 2, 3);
1242  ASSERT_EQ(p2.x, 2u);
1243  ASSERT_EQ(p2.y, 4u);
1244  ASSERT_EQ(p2.z, 6u);
1245  }
1246 
1247  {
1248  Vector3 p1(1, 2, 3);
1249  Vector3 p2 = p1 * Vector3(2, 3, 4);
1250  ASSERT_EQ(p2.x, 2u);
1251  ASSERT_EQ(p2.y, 6u);
1252  ASSERT_EQ(p2.z, 12u);
1253  }
1254 
1255  {
1256  Vector3 p1(2, 6, 12);
1257  Vector3 p2 = p1 / Vector3(2, 3, 4);
1258  ASSERT_EQ(p2.x, 1u);
1259  ASSERT_EQ(p2.y, 2u);
1260  ASSERT_EQ(p2.z, 3u);
1261  }
1262 }

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

◆ TEST() [107/389]

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

Definition at line 1264 of file geometry_unittests.cc.

1264  {
1265  // LHS
1266  {
1267  Vector3 p1(1, 2, 3);
1268  Vector3 p2 = p1 + 2.0f;
1269  ASSERT_EQ(p2.x, 3);
1270  ASSERT_EQ(p2.y, 4);
1271  ASSERT_EQ(p2.z, 5);
1272  }
1273 
1274  {
1275  Vector3 p1(1, 2, 3);
1276  Vector3 p2 = p1 - 2.0f;
1277  ASSERT_EQ(p2.x, -1);
1278  ASSERT_EQ(p2.y, 0);
1279  ASSERT_EQ(p2.z, 1);
1280  }
1281 
1282  {
1283  Vector3 p1(1, 2, 3);
1284  Vector3 p2 = p1 * 2.0f;
1285  ASSERT_EQ(p2.x, 2);
1286  ASSERT_EQ(p2.y, 4);
1287  ASSERT_EQ(p2.z, 6);
1288  }
1289 
1290  {
1291  Vector3 p1(2, 6, 12);
1292  Vector3 p2 = p1 / 2.0f;
1293  ASSERT_EQ(p2.x, 1);
1294  ASSERT_EQ(p2.y, 3);
1295  ASSERT_EQ(p2.z, 6);
1296  }
1297 
1298  // RHS
1299  {
1300  Vector3 p1(1, 2, 3);
1301  Vector3 p2 = 2.0f + p1;
1302  ASSERT_EQ(p2.x, 3);
1303  ASSERT_EQ(p2.y, 4);
1304  ASSERT_EQ(p2.z, 5);
1305  }
1306 
1307  {
1308  Vector3 p1(1, 2, 3);
1309  Vector3 p2 = 2.0f - p1;
1310  ASSERT_EQ(p2.x, 1);
1311  ASSERT_EQ(p2.y, 0);
1312  ASSERT_EQ(p2.z, -1);
1313  }
1314 
1315  {
1316  Vector3 p1(1, 2, 3);
1317  Vector3 p2 = 2.0f * p1;
1318  ASSERT_EQ(p2.x, 2);
1319  ASSERT_EQ(p2.y, 4);
1320  ASSERT_EQ(p2.z, 6);
1321  }
1322 
1323  {
1324  Vector3 p1(2, 6, 12);
1325  Vector3 p2 = 12.0f / p1;
1326  ASSERT_EQ(p2.x, 6);
1327  ASSERT_EQ(p2.y, 2);
1328  ASSERT_EQ(p2.z, 1);
1329  }
1330 }

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

◆ TEST() [108/389]

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

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

Definition at line 1180 of file geometry_unittests.cc.

1180  {
1181  {
1182  Vector3 p(1, 2, 4);
1183  p += Vector3(1, 2, 4);
1184  ASSERT_EQ(p.x, 2u);
1185  ASSERT_EQ(p.y, 4u);
1186  ASSERT_EQ(p.z, 8u);
1187  }
1188 
1189  {
1190  Vector3 p(3, 6, 8);
1191  p -= Vector3(1, 2, 3);
1192  ASSERT_EQ(p.x, 2u);
1193  ASSERT_EQ(p.y, 4u);
1194  ASSERT_EQ(p.z, 5u);
1195  }
1196 
1197  {
1198  Vector3 p(1, 2, 3);
1199  p *= Vector3(2, 3, 4);
1200  ASSERT_EQ(p.x, 2u);
1201  ASSERT_EQ(p.y, 6u);
1202  ASSERT_EQ(p.z, 12u);
1203  }
1204 
1205  {
1206  Vector3 p(1, 2, 3);
1207  p *= 2;
1208  ASSERT_EQ(p.x, 2u);
1209  ASSERT_EQ(p.y, 4u);
1210  ASSERT_EQ(p.z, 6u);
1211  }
1212 
1213  {
1214  Vector3 p(2, 6, 12);
1215  p /= Vector3(2, 3, 4);
1216  ASSERT_EQ(p.x, 1u);
1217  ASSERT_EQ(p.y, 2u);
1218  ASSERT_EQ(p.z, 3u);
1219  }
1220 
1221  {
1222  Vector3 p(2, 6, 12);
1223  p /= 2;
1224  ASSERT_EQ(p.x, 1u);
1225  ASSERT_EQ(p.y, 3u);
1226  ASSERT_EQ(p.z, 6u);
1227  }
1228 }

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

◆ TEST() [110/389]

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

Definition at line 1437 of file geometry_unittests.cc.

1437  {
1438  {
1439  ColorMatrix color_matrix = {
1440  1, 1, 1, 1, 1, //
1441  1, 1, 1, 1, 1, //
1442  1, 1, 1, 1, 1, //
1443  1, 1, 1, 1, 1, //
1444  };
1445  auto result = Color::White().ApplyColorMatrix(color_matrix);
1446  auto expected = Color(1, 1, 1, 1);
1447  ASSERT_COLOR_NEAR(result, expected);
1448  }
1449 
1450  {
1451  ColorMatrix color_matrix = {
1452  0.1, 0, 0, 0, 0.01, //
1453  0, 0.2, 0, 0, 0.02, //
1454  0, 0, 0.3, 0, 0.03, //
1455  0, 0, 0, 0.4, 0.04, //
1456  };
1457  auto result = Color::White().ApplyColorMatrix(color_matrix);
1458  auto expected = Color(0.11, 0.22, 0.33, 0.44);
1459  ASSERT_COLOR_NEAR(result, expected);
1460  }
1461 }

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

◆ TEST() [111/389]

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

Definition at line 1646 of file geometry_unittests.cc.

1646  {
1647  Color dst = ColorBlendTestData::kDestinationColor;
1648  for (size_t source_i = 0;
1649  source_i < sizeof(ColorBlendTestData::kSourceColors) / sizeof(Color);
1650  source_i++) {
1651  Color src = ColorBlendTestData::kSourceColors[source_i];
1652 
1653  Color expected;
1655  }
1656 }

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

◆ TEST() [112/389]

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

Definition at line 1397 of file geometry_unittests.cc.

1397  {
1398  {
1399  Color result = Color(0.5, 0.5, 0.5, 0.5).Clamp01();
1400  Color expected = Color(0.5, 0.5, 0.5, 0.5);
1401  ASSERT_COLOR_NEAR(result, expected);
1402  }
1403 
1404  {
1405  Color result = Color(-1, -1, -1, -1).Clamp01();
1406  Color expected = Color(0, 0, 0, 0);
1407  ASSERT_COLOR_NEAR(result, expected);
1408  }
1409 
1410  {
1411  Color result = Color(2, 2, 2, 2).Clamp01();
1412  Color expected = Color(1, 1, 1, 1);
1413  ASSERT_COLOR_NEAR(result, expected);
1414  }
1415 }

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

◆ TEST() [113/389]

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

Definition at line 1375 of file geometry_unittests.cc.

1375  {
1376  {
1377  Color a(0.0, 0.0, 0.0, 0.0);
1378  Color b(1.0, 1.0, 1.0, 1.0);
1379 
1380  ASSERT_COLOR_NEAR(Color::Lerp(a, b, 0.5), Color(0.5, 0.5, 0.5, 0.5));
1381  ASSERT_COLOR_NEAR(Color::Lerp(a, b, 0.0), a);
1382  ASSERT_COLOR_NEAR(Color::Lerp(a, b, 1.0), b);
1383  ASSERT_COLOR_NEAR(Color::Lerp(a, b, 0.2), Color(0.2, 0.2, 0.2, 0.2));
1384  }
1385 
1386  {
1387  Color a(0.2, 0.4, 1.0, 0.5);
1388  Color b(0.4, 1.0, 0.2, 0.3);
1389 
1390  ASSERT_COLOR_NEAR(Color::Lerp(a, b, 0.5), Color(0.3, 0.7, 0.6, 0.4));
1391  ASSERT_COLOR_NEAR(Color::Lerp(a, b, 0.0), a);
1392  ASSERT_COLOR_NEAR(Color::Lerp(a, b, 1.0), b);
1393  ASSERT_COLOR_NEAR(Color::Lerp(a, b, 0.2), Color(0.24, 0.52, 0.84, 0.46));
1394  }
1395 }

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

◆ TEST() [114/389]

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

Definition at line 1463 of file geometry_unittests.cc.

1463  {
1464  {
1465  auto result = Color::White().LinearToSRGB();
1466  auto expected = Color(1, 1, 1, 1);
1467  ASSERT_COLOR_NEAR(result, expected);
1468  }
1469 
1470  {
1471  auto result = Color::BlackTransparent().LinearToSRGB();
1472  auto expected = Color(0, 0, 0, 0);
1473  ASSERT_COLOR_NEAR(result, expected);
1474  }
1475 
1476  {
1477  auto result = Color(0.2, 0.4, 0.6, 0.8).LinearToSRGB();
1478  auto expected = Color(0.484529, 0.665185, 0.797738, 0.8);
1479  ASSERT_COLOR_NEAR(result, expected);
1480  }
1481 }

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

◆ TEST() [115/389]

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

Definition at line 1417 of file geometry_unittests.cc.

1417  {
1418  {
1419  Color a = Color::MakeRGBA8(0, 0, 0, 0);
1420  Color b = Color::BlackTransparent();
1421  ASSERT_COLOR_NEAR(a, b);
1422  }
1423 
1424  {
1425  Color a = Color::MakeRGBA8(255, 255, 255, 255);
1426  Color b = Color::White();
1427  ASSERT_COLOR_NEAR(a, b);
1428  }
1429 
1430  {
1431  Color a = Color::MakeRGBA8(63, 127, 191, 127);
1432  Color b(0.247059, 0.498039, 0.74902, 0.498039);
1433  ASSERT_COLOR_NEAR(a, b);
1434  }
1435 }

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

◆ TEST() [116/389]

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

Definition at line 1332 of file geometry_unittests.cc.

1332  {
1333  {
1334  Color a(1.0, 0.5, 0.2, 0.5);
1335  Color premultiplied = a.Premultiply();
1336  Color expected = Color(0.5, 0.25, 0.1, 0.5);
1337  ASSERT_COLOR_NEAR(premultiplied, expected);
1338  }
1339 
1340  {
1341  Color a(0.5, 0.25, 0.1, 0.5);
1342  Color unpremultiplied = a.Unpremultiply();
1343  Color expected = Color(1.0, 0.5, 0.2, 0.5);
1344  ASSERT_COLOR_NEAR(unpremultiplied, expected);
1345  }
1346 
1347  {
1348  Color a(0.5, 0.25, 0.1, 0.0);
1349  Color unpremultiplied = a.Unpremultiply();
1350  Color expected = Color(0.0, 0.0, 0.0, 0.0);
1351  ASSERT_COLOR_NEAR(unpremultiplied, expected);
1352  }
1353 }

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

◆ TEST() [117/389]

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

Definition at line 1755 of file geometry_unittests.cc.

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

◆ TEST() [118/389]

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

Definition at line 1355 of file geometry_unittests.cc.

1355  {
1356  {
1357  Color a(1.0, 0.5, 0.2, 0.5);
1358  std::array<uint8_t, 4> expected = {255, 128, 51, 128};
1359  ASSERT_ARRAY_4_NEAR(a.ToR8G8B8A8(), expected);
1360  }
1361 
1362  {
1363  Color a(0.0, 0.0, 0.0, 0.0);
1364  std::array<uint8_t, 4> expected = {0, 0, 0, 0};
1365  ASSERT_ARRAY_4_NEAR(a.ToR8G8B8A8(), expected);
1366  }
1367 
1368  {
1369  Color a(1.0, 1.0, 1.0, 1.0);
1370  std::array<uint8_t, 4> expected = {255, 255, 255, 255};
1371  ASSERT_ARRAY_4_NEAR(a.ToR8G8B8A8(), expected);
1372  }
1373 }

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

◆ TEST() [119/389]

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

Definition at line 1483 of file geometry_unittests.cc.

1483  {
1484  {
1485  auto result = Color::White().SRGBToLinear();
1486  auto expected = Color(1, 1, 1, 1);
1487  ASSERT_COLOR_NEAR(result, expected);
1488  }
1489 
1490  {
1491  auto result = Color::BlackTransparent().SRGBToLinear();
1492  auto expected = Color(0, 0, 0, 0);
1493  ASSERT_COLOR_NEAR(result, expected);
1494  }
1495 
1496  {
1497  auto result = Color(0.2, 0.4, 0.6, 0.8).SRGBToLinear();
1498  auto expected = Color(0.0331048, 0.132868, 0.318547, 0.8);
1499  ASSERT_COLOR_NEAR(result, expected);
1500  }
1501 }

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

◆ TEST() [120/389]

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

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

Definition at line 1777 of file geometry_unittests.cc.

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

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

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

Definition at line 1847 of file geometry_unittests.cc.

1847  {
1848 #if defined(FML_OS_MACOSX) || defined(FML_OS_IOS) || \
1849  defined(FML_OS_IOS_SIMULATOR)
1850  ASSERT_EQ(ScalarToHalf(0.0), 0.0f16);
1851  ASSERT_EQ(ScalarToHalf(0.05), 0.05f16);
1852  ASSERT_EQ(ScalarToHalf(2.43), 2.43f16);
1853  ASSERT_EQ(ScalarToHalf(-1.45), -1.45f16);
1854 
1855  // 65504 is the largest possible half.
1856  ASSERT_EQ(ScalarToHalf(65504.0f), 65504.0f16);
1857  ASSERT_EQ(ScalarToHalf(65504.0f + 1), 65504.0f16);
1858 
1859  // Colors
1860  ASSERT_EQ(HalfVector4(Color::Red()),
1861  HalfVector4(1.0f16, 0.0f16, 0.0f16, 1.0f16));
1862  ASSERT_EQ(HalfVector4(Color::Green()),
1863  HalfVector4(0.0f16, 1.0f16, 0.0f16, 1.0f16));
1864  ASSERT_EQ(HalfVector4(Color::Blue()),
1865  HalfVector4(0.0f16, 0.0f16, 1.0f16, 1.0f16));
1866  ASSERT_EQ(HalfVector4(Color::Black().WithAlpha(0)),
1867  HalfVector4(0.0f16, 0.0f16, 0.0f16, 0.0f16));
1868 
1869  ASSERT_EQ(HalfVector3(Vector3(4.0, 6.0, -1.0)),
1870  HalfVector3(4.0f16, 6.0f16, -1.0f16));
1871  ASSERT_EQ(HalfVector2(Vector2(4.0, 6.0)), HalfVector2(4.0f16, 6.0f16));
1872 
1873  ASSERT_EQ(Half(0.5f), Half(0.5f16));
1874  ASSERT_EQ(Half(0.5), Half(0.5f16));
1875  ASSERT_EQ(Half(5), Half(5.0f16));
1876 #else
1877  GTEST_SKIP() << "Half-precision floats (IEEE 754) are not portable and "
1878  "only used on Apple platforms.";
1879 #endif // FML_OS_MACOSX || FML_OS_IOS || FML_OS_IOS_SIMULATOR
1880 }

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

◆ TEST() [123/389]

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

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

Definition at line 79 of file geometry_unittests.cc.

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

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

◆ TEST() [125/389]

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

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

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

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 }

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

◆ TEST() [129/389]

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

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

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

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

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

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

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

Definition at line 1680 of file geometry_unittests.cc.

1680  {
1681  {
1682  std::stringstream stream;
1683  Matrix m;
1684  stream << m;
1685  ASSERT_EQ(stream.str(), R"((
1686  1.000000, 0.000000, 0.000000, 0.000000,
1687  0.000000, 1.000000, 0.000000, 0.000000,
1688  0.000000, 0.000000, 1.000000, 0.000000,
1689  0.000000, 0.000000, 0.000000, 1.000000,
1690 ))");
1691  }
1692 
1693  {
1694  std::stringstream stream;
1695  Matrix m = Matrix::MakeTranslation(Vector3(10, 20, 30));
1696  stream << m;
1697 
1698  ASSERT_EQ(stream.str(), R"((
1699  1.000000, 0.000000, 0.000000, 10.000000,
1700  0.000000, 1.000000, 0.000000, 20.000000,
1701  0.000000, 0.000000, 1.000000, 30.000000,
1702  0.000000, 0.000000, 0.000000, 1.000000,
1703 ))");
1704  }
1705 }

References impeller::Matrix::MakeTranslation().

◆ TEST() [136/389]

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

Definition at line 298 of file geometry_unittests.cc.

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

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

◆ TEST() [137/389]

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

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

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

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

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 }

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

◆ TEST() [142/389]

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

Definition at line 1067 of file geometry_unittests.cc.

1067  {
1068  Point p(1.5, 2.3);
1069  Point result = p.Ceil();
1070  Point expected(2, 3);
1071  ASSERT_POINT_NEAR(result, expected);
1072 }

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

◆ TEST() [143/389]

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

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

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

Definition at line 1046 of file geometry_unittests.cc.

1046  {
1047  Point p(1.5, 2.3);
1048  Point result = p.Floor();
1049  Point expected(1, 2);
1050  ASSERT_POINT_NEAR(result, expected);
1051 }

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

◆ TEST() [146/389]

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

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

Definition at line 1109 of file geometry_unittests.cc.

1109  {
1110  Point p(1, 2);
1111  Point result = p.Lerp({5, 10}, 0.75);
1112  Point expected(4, 8);
1113  ASSERT_POINT_NEAR(result, expected);
1114 }

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

◆ TEST() [148/389]

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

Definition at line 1025 of file geometry_unittests.cc.

1025  {
1026  Point p(1, 2);
1027  Point result = p.Max({0, 10});
1028  Point expected(1, 10);
1029  ASSERT_POINT_NEAR(result, expected);
1030 }

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

◆ TEST() [149/389]

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 }

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

◆ TEST() [150/389]

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

Definition at line 1707 of file geometry_unittests.cc.

1707  {
1708  {
1709  std::stringstream stream;
1710  Point m;
1711  stream << m;
1712  ASSERT_EQ(stream.str(), "(0, 0)");
1713  }
1714 
1715  {
1716  std::stringstream stream;
1717  Point m(13, 37);
1718  stream << m;
1719  ASSERT_EQ(stream.str(), "(13, 37)");
1720  }
1721 }

◆ TEST() [151/389]

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 }

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

◆ TEST() [152/389]

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

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

Definition at line 1088 of file geometry_unittests.cc.

1088  {
1089  Point p(1.5, 2.3);
1090  Point result = p.Round();
1091  Point expected(2, 2);
1092  ASSERT_POINT_NEAR(result, expected);
1093 }

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

◆ TEST() [154/389]

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 }

References ASSERT_QUATERNION_NEAR, and impeller::kPiOver4.

◆ TEST() [155/389]

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 }

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

◆ TEST() [156/389]

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

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

Definition at line 31 of file geometry_unittests.cc.

31  {
32  ASSERT_FALSE(ScalarNearlyEqual(0.0021f, 0.001f));
33  ASSERT_TRUE(ScalarNearlyEqual(0.0019f, 0.001f));
34  ASSERT_TRUE(ScalarNearlyEqual(0.002f, 0.001f, 0.0011f));
35  ASSERT_FALSE(ScalarNearlyEqual(0.002f, 0.001f, 0.0009f));
36  ASSERT_TRUE(ScalarNearlyEqual(
37  1.0f, 1.0f + std::numeric_limits<float>::epsilon() * 4));
38 }

References impeller::ScalarNearlyEqual().

◆ TEST() [158/389]

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

Definition at line 1164 of file geometry_unittests.cc.

1164  {
1165  {
1166  SeparatedVector2 v(Vector2(10, 0));
1167  Radians actual = v.AngleTo(SeparatedVector2(Vector2(5, 0)));
1168  Radians expected = Radians{0};
1169  ASSERT_NEAR(actual.radians, expected.radians, kEhCloseEnough);
1170  }
1171 
1172  {
1173  SeparatedVector2 v(Vector2(10, 0));
1174  Radians actual = v.AngleTo(SeparatedVector2(Vector2(0, -5)));
1175  Radians expected = Radians{-kPi / 2};
1176  ASSERT_NEAR(actual.radians, expected.radians, kEhCloseEnough);
1177  }
1178 }

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

◆ TEST() [159/389]

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

Definition at line 1141 of file geometry_unittests.cc.

1141  {
1142  // Parallel
1143  {
1144  SeparatedVector2 v(Vector2(10, 0));
1145  Scalar actual = v.GetAlignment(SeparatedVector2(Vector2(5, 0)));
1146  ASSERT_NEAR(actual, 1, kEhCloseEnough);
1147  }
1148 
1149  // Perpendicular
1150  {
1151  SeparatedVector2 v(Vector2(10, 0));
1152  Scalar actual = v.GetAlignment(SeparatedVector2(Vector2(0, 5)));
1153  ASSERT_NEAR(actual, 0, kEhCloseEnough);
1154  }
1155 
1156  // Opposite parallel
1157  {
1158  SeparatedVector2 v(Vector2(0, 10));
1159  Scalar actual = v.GetAlignment(SeparatedVector2(Vector2(0, -5)));
1160  ASSERT_NEAR(actual, -1, kEhCloseEnough);
1161  }
1162 }

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

◆ TEST() [160/389]

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

Definition at line 1136 of file geometry_unittests.cc.

1136  {
1137  SeparatedVector2 v(Vector2(10, 0));
1138  ASSERT_POINT_NEAR(v.GetVector(), Vector2(10, 0));
1139 }

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

◆ TEST() [161/389]

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

Definition at line 1130 of file geometry_unittests.cc.

1130  {
1131  SeparatedVector2 v(Vector2(10, 0));
1132  ASSERT_POINT_NEAR(v.direction, Vector2(1, 0));
1133  ASSERT_NEAR(v.magnitude, 10, kEhCloseEnough);
1134 }

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

◆ TEST() [162/389]

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

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

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

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

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

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

Definition at line 1771 of file geometry_unittests.cc.

1771  {
1772  ASSERT_EQ(Color::ToIColor(Color(0, 0, 0, 0)), 0u);
1773  ASSERT_EQ(Color::ToIColor(Color(1.0, 1.0, 1.0, 1.0)), 0xFFFFFFFF);
1774  ASSERT_EQ(Color::ToIColor(Color(0.5, 0.5, 1.0, 1.0)), 0xFF8080FF);
1775 }

References impeller::Color::ToIColor().

◆ TEST() [168/389]

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

Definition at line 1074 of file geometry_unittests.cc.

1074  {
1075  Vector3 p(1.5, 2.3, 3.9);
1076  Vector3 result = p.Ceil();
1077  Vector3 expected(2, 3, 4);
1078  ASSERT_VECTOR3_NEAR(result, expected);
1079 }

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

◆ TEST() [169/389]

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

Definition at line 1053 of file geometry_unittests.cc.

1053  {
1054  Vector3 p(1.5, 2.3, 3.9);
1055  Vector3 result = p.Floor();
1056  Vector3 expected(1, 2, 3);
1057  ASSERT_VECTOR3_NEAR(result, expected);
1058 }

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

◆ TEST() [170/389]

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

Definition at line 1116 of file geometry_unittests.cc.

1116  {
1117  Vector3 p(1, 2, 3);
1118  Vector3 result = p.Lerp({5, 10, 15}, 0.75);
1119  Vector3 expected(4, 8, 12);
1120  ASSERT_VECTOR3_NEAR(result, expected);
1121 }

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

◆ TEST() [171/389]

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

Definition at line 1032 of file geometry_unittests.cc.

1032  {
1033  Vector3 p(1, 2, 3);
1034  Vector3 result = p.Max({0, 10, 2});
1035  Vector3 expected(1, 10, 3);
1036  ASSERT_VECTOR3_NEAR(result, expected);
1037 }

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

◆ TEST() [172/389]

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

Definition at line 1011 of file geometry_unittests.cc.

1011  {
1012  Vector3 p(1, 2, 3);
1013  Vector3 result = p.Min({0, 10, 2});
1014  Vector3 expected(0, 2, 2);
1015  ASSERT_VECTOR3_NEAR(result, expected);
1016 }

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

◆ TEST() [173/389]

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

Definition at line 1723 of file geometry_unittests.cc.

1723  {
1724  {
1725  std::stringstream stream;
1726  Vector3 m;
1727  stream << m;
1728  ASSERT_EQ(stream.str(), "(0, 0, 0)");
1729  }
1730 
1731  {
1732  std::stringstream stream;
1733  Vector3 m(1, 2, 3);
1734  stream << m;
1735  ASSERT_EQ(stream.str(), "(1, 2, 3)");
1736  }
1737 }

◆ TEST() [174/389]

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

Definition at line 1095 of file geometry_unittests.cc.

1095  {
1096  Vector3 p(1.5, 2.3, 3.9);
1097  Vector3 result = p.Round();
1098  Vector3 expected(2, 2, 4);
1099  ASSERT_VECTOR3_NEAR(result, expected);
1100 }

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

◆ TEST() [175/389]

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

Definition at line 1081 of file geometry_unittests.cc.

1081  {
1082  Vector4 p(1.5, 2.3, 3.9, 4.0);
1083  Vector4 result = p.Ceil();
1084  Vector4 expected(2, 3, 4, 4);
1085  ASSERT_VECTOR4_NEAR(result, expected);
1086 }

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

◆ TEST() [176/389]

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

Definition at line 1060 of file geometry_unittests.cc.

1060  {
1061  Vector4 p(1.5, 2.3, 3.9, 4.0);
1062  Vector4 result = p.Floor();
1063  Vector4 expected(1, 2, 3, 4);
1064  ASSERT_VECTOR4_NEAR(result, expected);
1065 }

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

◆ TEST() [177/389]

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

Definition at line 1123 of file geometry_unittests.cc.

1123  {
1124  Vector4 p(1, 2, 3, 4);
1125  Vector4 result = p.Lerp({5, 10, 15, 20}, 0.75);
1126  Vector4 expected(4, 8, 12, 16);
1127  ASSERT_VECTOR4_NEAR(result, expected);
1128 }

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

◆ TEST() [178/389]

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

Definition at line 1039 of file geometry_unittests.cc.

1039  {
1040  Vector4 p(1, 2, 3, 4);
1041  Vector4 result = p.Max({0, 10, 2, 1});
1042  Vector4 expected(1, 10, 3, 4);
1043  ASSERT_VECTOR4_NEAR(result, expected);
1044 }

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

◆ TEST() [179/389]

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

Definition at line 1018 of file geometry_unittests.cc.

1018  {
1019  Vector4 p(1, 2, 3, 4);
1020  Vector4 result = p.Min({0, 10, 2, 1});
1021  Vector4 expected(0, 2, 2, 1);
1022  ASSERT_VECTOR4_NEAR(result, expected);
1023 }

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

◆ TEST() [180/389]

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

Definition at line 1739 of file geometry_unittests.cc.

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

◆ TEST() [181/389]

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

Definition at line 1102 of file geometry_unittests.cc.

1102  {
1103  Vector4 p(1.5, 2.3, 3.9, 4.0);
1104  Vector4 result = p.Round();
1105  Vector4 expected(2, 2, 4, 4);
1106  ASSERT_VECTOR4_NEAR(result, expected);
1107 }

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

◆ TEST() [182/389]

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

Definition at line 70 of file matrix_filter_contents_unittests.cc.

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

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

◆ TEST() [183/389]

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

Definition at line 82 of file matrix_filter_contents_unittests.cc.

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

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

◆ TEST() [184/389]

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

Definition at line 50 of file matrix_filter_contents_unittests.cc.

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

References impeller::MatrixFilterContents::GetFilterCoverage().

◆ TEST() [185/389]

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

Definition at line 59 of file matrix_filter_contents_unittests.cc.

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

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

◆ TEST() [186/389]

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

Definition at line 45 of file matrix_filter_contents_unittests.cc.

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

References impeller::MatrixFilterContents::IsTranslationOnly().

◆ TEST() [187/389]

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 impeller::Matrix::Equals().

◆ TEST() [188/389]

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

Definition at line 176 of file matrix_unittests.cc.

176  {
177  Matrix m = Matrix::MakeScale({-2, 1, 1});
178 
179  EXPECT_EQ(m.GetMaxBasisLengthXY(), 2);
180 
181  m = Matrix::MakeScale({1, -3, 1});
182 
183  EXPECT_EQ(m.GetMaxBasisLengthXY(), 3);
184 }

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

◆ TEST() [189/389]

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

Definition at line 187 of file matrix_unittests.cc.

187  {
188  Matrix m = Matrix::MakeScale({2.625e+20, 2.625e+20, 1});
189  EXPECT_NEAR(m.GetMaxBasisLengthXY(), 2.625e+20, 1e+20);
190 
191  m = Matrix::MakeScale({2.625e-20, 2.625e-20, 1});
192  EXPECT_NEAR(m.GetMaxBasisLengthXY(), 2.625e-20, 1e-20);
193 }

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

◆ TEST() [190/389]

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

Definition at line 195 of file matrix_unittests.cc.

195  {
196  Matrix m = Matrix::MakeScale({2.625e+20, 2.625e+20, 1});
197  m.e[0][1] = 2;
198 
199  EXPECT_TRUE(std::isinf(m.GetMaxBasisLengthXY()));
200 }

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

◆ TEST() [191/389]

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

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

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

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

Definition at line 116 of file matrix_unittests.cc.

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

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

◆ TEST() [195/389]

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

Definition at line 83 of file matrix_unittests.cc.

83  {
84  EXPECT_TRUE(Matrix().IsAligned2D());
85  EXPECT_TRUE(Matrix::MakeScale({1.0f, 1.0f, 2.0f}).IsAligned2D());
86 
87  auto test = [](int index, bool expect) {
88  Matrix matrix;
89  EXPECT_TRUE(matrix.IsAligned2D());
90  matrix.m[index] = 0.5f;
91  EXPECT_EQ(matrix.IsAligned2D(), expect) << "index: " << index;
92  };
93 
94  // clang-format off
95  test( 0, true); test( 1, false); test( 2, true); test( 3, false);
96  test( 4, false); test( 5, true); test( 6, true); test( 7, false);
97  test( 8, true); test( 9, true); test(10, true); test(11, true);
98  test(12, true); test(13, true); test(14, true); test(15, false);
99  // clang-format on
100 
101  // True for quadrant rotations from -250 to +250 full circles
102  for (int i = -1000; i < 1000; i++) {
103  Degrees d = Degrees(i * 90);
104  Matrix matrix = Matrix::MakeRotationZ(Degrees(d));
105  EXPECT_TRUE(matrix.IsAligned2D()) << "degrees: " << d.degrees;
106  }
107 
108  // False for half degree rotations from -999.5 to +1000.5 degrees
109  for (int i = -1000; i < 1000; i++) {
110  Degrees d = Degrees(i + 0.5f);
111  Matrix matrix = Matrix::MakeRotationZ(Degrees(d));
112  EXPECT_FALSE(matrix.IsAligned2D()) << "degrees: " << d.degrees;
113  }
114 }

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

◆ TEST() [196/389]

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(), and MatrixNear().

◆ TEST() [197/389]

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 impeller::Matrix::Equals(), and impeller::Matrix::Translate().

◆ TEST() [198/389]

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

Definition at line 163 of file matrix_unittests.cc.

163  {
164  Matrix matrix = Matrix::MakeColumn(
165  // clang-format off
166  2.0f, 3.0f, 5.0f, 7.0f,
167  11.0f, 13.0f, 17.0f, 19.0f,
168  23.0f, 29.0f, 31.0f, 37.0f,
169  41.0f, 43.0f, 47.0f, 53.0f
170  // clang-format on
171  );
172  EXPECT_EQ(matrix.TransformHomogenous({1.0f, -1.0f}),
173  Vector3(32.0f, 33.0f, 41.0f));
174 }

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

◆ TEST() [199/389]

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

Definition at line 202 of file matrix_unittests.cc.

202  {
203  Matrix m = Matrix::MakeRow(1.0, 0.0, 0.0, 10.0, //
204  0.0, 1.0, 0.0, 20.0, //
205  0.0, 0.0, 1.0, 0.0, //
206  0.0, 2.0, 0.0, 30.0);
207  Matrix result = m.Translate({100, 200});
208  EXPECT_TRUE(MatrixNear(result, Matrix::MakeRow(1.0, 0.0, 0.0, 110.0, //
209  0.0, 1.0, 0.0, 220.0, //
210  0.0, 0.0, 1.0, 0.0, //
211  0.0, 2.0, 0.0, 430.0)));
212 }

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

◆ TEST() [200/389]

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

Definition at line 347 of file path_unittests.cc.

347  {
348  PathBuilder builder;
349  auto path =
350  builder.AddCubicCurve({120, 160}, {25, 200}, {220, 260}, {220, 40})
351  .TakePath();
352  auto box = path.GetBoundingBox();
353  Rect expected = Rect::MakeXYWH(93.9101, 40, 126.09, 158.862);
354  ASSERT_TRUE(box.has_value());
355  ASSERT_RECT_NEAR(box.value_or(Rect::MakeMaximum()), expected);
356 }

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

◆ TEST() [201/389]

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

Definition at line 358 of file path_unittests.cc.

358  {
359  PathBuilder builder;
360  builder.AddRoundedRect(Rect::MakeXYWH(10, 10, 300, 300), {50, 50, 50, 50});
361  auto path = builder.TakePath();
362  auto actual = path.GetBoundingBox();
363  Rect expected = Rect::MakeXYWH(10, 10, 300, 300);
364 
365  ASSERT_TRUE(actual.has_value());
366  ASSERT_RECT_NEAR(actual.value_or(Rect::MakeMaximum()), expected);
367 }

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

◆ TEST() [202/389]

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

Definition at line 527 of file path_unittests.cc.

527  {
528  PathBuilder builder;
529  builder.MoveTo({10, 10});
530  builder.LineTo({20, 20});
531  builder.SetBounds(Rect::MakeLTRB(0, 0, 100, 100));
532  builder.SetConvexity(Convexity::kConvex);
533 
534  auto path_a = builder.TakePath(FillType::kOdd);
535  // NOLINTNEXTLINE(performance-unnecessary-copy-initialization)
536  auto path_b = path_a;
537 
538  EXPECT_EQ(path_a.GetBoundingBox(), path_b.GetBoundingBox());
539  EXPECT_EQ(path_a.GetFillType(), path_b.GetFillType());
540  EXPECT_EQ(path_a.IsConvex(), path_b.IsConvex());
541 
542  auto poly_a = path_a.CreatePolyline(1.0);
543  auto poly_b = path_b.CreatePolyline(1.0);
544 
545  ASSERT_EQ(poly_a.points->size(), poly_b.points->size());
546  ASSERT_EQ(poly_a.contours.size(), poly_b.contours.size());
547 
548  for (auto i = 0u; i < poly_a.points->size(); i++) {
549  EXPECT_EQ((*poly_a.points)[i], (*poly_b.points)[i]);
550  }
551 
552  for (auto i = 0u; i < poly_a.contours.size(); i++) {
553  EXPECT_EQ(poly_a.contours[i].start_index, poly_b.contours[i].start_index);
554  EXPECT_EQ(poly_a.contours[i].start_direction,
555  poly_b.contours[i].start_direction);
556  }
557 }

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

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

Definition at line 497 of file path_unittests.cc.

497  {
498  PathBuilder builder;
499  auto path = builder.LineTo({0, 10})
500  .LineTo({10, 10})
501  .MoveTo({30, 30}) // Moves to (30, 30)
502  .Close() // No Op
503  .Close() // Still No op
504  .TakePath();
505 
506  EXPECT_EQ(path.GetComponentCount(), 4u);
507  EXPECT_EQ(path.GetComponentCount(Path::ComponentType::kLinear), 2u);
508  EXPECT_EQ(path.GetComponentCount(Path::ComponentType::kContour), 2u);
509 }

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

◆ TEST() [204/389]

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

Definition at line 511 of file path_unittests.cc.

511  {
512  PathBuilder builder;
513  // Create a path that has a current position at the origin when close is
514  // called. This should not insert a new line segment
515  auto path = builder.LineTo({10, 0})
516  .LineTo({10, 10})
517  .LineTo({0, 10})
518  .LineTo({0, 0})
519  .Close()
520  .TakePath();
521 
522  EXPECT_EQ(path.GetComponentCount(), 6u);
523  EXPECT_EQ(path.GetComponentCount(Path::ComponentType::kLinear), 4u);
524  EXPECT_EQ(path.GetComponentCount(Path::ComponentType::kContour), 2u);
525 }

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

◆ TEST() [205/389]

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

Definition at line 332 of file path_unittests.cc.

332  {
333  PathBuilder builder;
334  auto path =
335  builder.CubicCurveTo(Point(10, 10), Point(-10, -10), Point(20, 20))
336  .TakePath();
337 
338  CubicPathComponent cubic;
339  path.GetCubicComponentAtIndex(1, cubic);
340 
341  EXPECT_EQ(cubic.p1, Point(0, 0));
342  EXPECT_EQ(cubic.cp1, Point(10, 10));
343  EXPECT_EQ(cubic.cp2, Point(-10, -10));
344  EXPECT_EQ(cubic.p2, Point(20, 20));
345 }

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

◆ TEST() [206/389]

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

Definition at line 16 of file path_unittests.cc.

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

References polyline.

◆ TEST() [207/389]

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

Definition at line 392 of file path_unittests.cc.

392  {
393  auto path = PathBuilder{}.TakePath();
394  ASSERT_EQ(path.GetComponentCount(), 1u);
395 
396  ContourComponent c;
397  path.GetContourComponentAtIndex(0, c);
398  ASSERT_POINT_NEAR(c.destination, Point());
399 
400  Path::Polyline polyline = path.CreatePolyline(1.0f);
401  ASSERT_TRUE(polyline.points->empty());
402  ASSERT_TRUE(polyline.contours.empty());
403 }

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

◆ TEST() [208/389]

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

Definition at line 26 of file path_unittests.cc.

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

References impeller::PathBuilder::TakePath().

◆ TEST() [209/389]

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

Definition at line 369 of file path_unittests.cc.

369  {
370  CubicPathComponent cubic{{11.769268, 252.883148},
371  {-6.2857933, 204.356461},
372  {-4.53997231, 156.552902},
373  {17.0067291, 109.472488}};
374  auto points = cubic.Extrema();
375 
376  ASSERT_EQ(points.size(), static_cast<size_t>(3));
377  ASSERT_POINT_NEAR(points[2], cubic.Solve(0.455916));
378 }

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

◆ TEST() [210/389]

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

Definition at line 168 of file path_unittests.cc.

168  {
169  Path::Polyline polyline = PathBuilder{}
170  .AddRect(Rect::MakeLTRB(50, 60, 70, 80))
171  .TakePath()
172  .CreatePolyline(1.0f);
173  ASSERT_EQ(polyline.contours.size(), 1u);
174  ASSERT_TRUE(polyline.contours[0].is_closed);
175  ASSERT_EQ(polyline.contours[0].start_index, 0u);
176  ASSERT_EQ(polyline.points->size(), 5u);
177  ASSERT_EQ(polyline.GetPoint(0), Point(50, 60));
178  ASSERT_EQ(polyline.GetPoint(1), Point(70, 60));
179  ASSERT_EQ(polyline.GetPoint(2), Point(70, 80));
180  ASSERT_EQ(polyline.GetPoint(3), Point(50, 80));
181  ASSERT_EQ(polyline.GetPoint(4), Point(50, 60));
182 }

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

◆ TEST() [211/389]

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

Definition at line 559 of file path_unittests.cc.

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

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

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

Definition at line 52 of file path_unittests.cc.

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

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

◆ TEST() [213/389]

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

Definition at line 276 of file path_unittests.cc.

276  {
277  PathBuilder builder;
278  auto path_1 = builder.AddLine({0, 0}, {1, 1}).TakePath();
279 
280  ASSERT_EQ(path_1.GetBoundingBox().value_or(Rect::MakeMaximum()),
281  Rect::MakeLTRB(0, 0, 1, 1));
282 
283  auto path_2 = builder.AddLine({-1, -1}, {1, 1}).TakePath();
284 
285  // Verify that PathBuilder recomputes the bounds.
286  ASSERT_EQ(path_2.GetBoundingBox().value_or(Rect::MakeMaximum()),
287  Rect::MakeLTRB(-1, -1, 1, 1));
288 
289  // PathBuilder can set the bounds to whatever it wants
290  auto path_3 = builder.AddLine({0, 0}, {1, 1})
291  .SetBounds(Rect::MakeLTRB(0, 0, 100, 100))
292  .TakePath();
293 
294  ASSERT_EQ(path_3.GetBoundingBox().value_or(Rect::MakeMaximum()),
295  Rect::MakeLTRB(0, 0, 100, 100));
296 }

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

◆ TEST() [214/389]

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

Definition at line 33 of file path_unittests.cc.

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

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

◆ TEST() [215/389]

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

Definition at line 133 of file path_unittests.cc.

133  {
134  Path::Polyline polyline = PathBuilder{}
135  .AddLine({100, 100}, {200, 100})
136  .MoveTo({100, 200})
137  .LineTo({150, 250})
138  .LineTo({200, 200})
139  .Close()
140  .TakePath()
141  .CreatePolyline(1.0f);
142  ASSERT_EQ(polyline.points->size(), 6u);
143  ASSERT_EQ(polyline.contours.size(), 2u);
144  ASSERT_EQ(polyline.contours[0].is_closed, false);
145  ASSERT_EQ(polyline.contours[0].start_index, 0u);
146  ASSERT_EQ(polyline.contours[1].is_closed, true);
147  ASSERT_EQ(polyline.contours[1].start_index, 2u);
148 }

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

◆ TEST() [216/389]

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

Definition at line 380 of file path_unittests.cc.

380  {
381  PathBuilder builder;
382  // Straight diagonal line.
383  builder.AddCubicCurve({0, 1}, {2, 3}, {4, 5}, {6, 7});
384  auto path = builder.TakePath();
385  auto actual = path.GetBoundingBox();
386  auto expected = Rect::MakeLTRB(0, 1, 6, 7);
387 
388  ASSERT_TRUE(actual.has_value());
389  ASSERT_RECT_NEAR(actual.value_or(Rect::MakeMaximum()), expected);
390 }

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

◆ TEST() [217/389]

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

Definition at line 298 of file path_unittests.cc.

298  {
299  PathBuilder builder;
300  auto path = builder.HorizontalLineTo(10).TakePath();
301 
302  LinearPathComponent linear;
303  path.GetLinearComponentAtIndex(1, linear);
304 
305  EXPECT_EQ(linear.p1, Point(0, 0));
306  EXPECT_EQ(linear.p2, Point(10, 0));
307 }

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

◆ TEST() [218/389]

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

Definition at line 184 of file path_unittests.cc.

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

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

◆ TEST() [219/389]

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

Definition at line 240 of file path_unittests.cc.

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

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

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

Definition at line 309 of file path_unittests.cc.

309  {
310  PathBuilder builder;
311  auto path = builder.VerticalLineTo(10).TakePath();
312 
313  LinearPathComponent linear;
314  path.GetLinearComponentAtIndex(1, linear);
315 
316  EXPECT_EQ(linear.p1, Point(0, 0));
317  EXPECT_EQ(linear.p2, Point(0, 10));
318 }

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

◆ TEST() [221/389]

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

Definition at line 213 of file path_unittests.cc.

213  {
214  auto point_buffer = std::make_unique<std::vector<Point>>();
215  auto point_buffer_address = reinterpret_cast<uintptr_t>(point_buffer.get());
216  Path::Polyline polyline =
217  PathBuilder{}
218  .MoveTo({50, 50})
219  .LineTo({100, 100})
220  .TakePath()
221  .CreatePolyline(
222  1.0f, std::move(point_buffer),
223  [point_buffer_address](
224  Path::Polyline::PointBufferPtr point_buffer) {
225  ASSERT_EQ(point_buffer->size(), 0u);
226  ASSERT_EQ(point_buffer_address,
227  reinterpret_cast<uintptr_t>(point_buffer.get()));
228  });
229 }

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

◆ TEST() [222/389]

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

Definition at line 231 of file path_unittests.cc.

231  {
232  EXPECT_DEATH_IF_SUPPORTED(PathBuilder{}
233  .MoveTo({50, 50})
234  .LineTo({100, 100})
235  .TakePath()
236  .CreatePolyline(1.0f, nullptr),
237  "");
238 }

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

◆ TEST() [223/389]

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

Definition at line 150 of file path_unittests.cc.

150  {
151  Path::Polyline polyline = PathBuilder{}
152  .AddLine({100, 100}, {200, 100})
153  .MoveTo({100, 200})
154  .LineTo({150, 250})
155  .LineTo({200, 200})
156  .Close()
157  .TakePath()
158  .CreatePolyline(1.0f);
159  size_t a1, a2, b1, b2;
160  std::tie(a1, a2) = polyline.GetContourPointBounds(0);
161  std::tie(b1, b2) = polyline.GetContourPointBounds(1);
162  ASSERT_EQ(a1, 0u);
163  ASSERT_EQ(a2, 2u);
164  ASSERT_EQ(b1, 2u);
165  ASSERT_EQ(b2, 6u);
166 }

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

◆ TEST() [224/389]

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

Definition at line 320 of file path_unittests.cc.

320  {
321  PathBuilder builder;
322  auto path = builder.QuadraticCurveTo(Point(10, 10), Point(20, 20)).TakePath();
323 
324  QuadraticPathComponent quad;
325  path.GetQuadraticComponentAtIndex(1, quad);
326 
327  EXPECT_EQ(quad.p1, Point(0, 0));
328  EXPECT_EQ(quad.cp, Point(10, 10));
329  EXPECT_EQ(quad.p2, Point(20, 20));
330 }

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

◆ TEST() [225/389]

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

Definition at line 483 of file path_unittests.cc.

483  {
484  PathBuilder builder;
485  auto path = builder.LineTo({0, 10})
486  .LineTo({10, 10})
487  .Close() // Returns to (0, 0)
488  .Close() // No Op
489  .Close() // Still No op
490  .TakePath();
491 
492  EXPECT_EQ(path.GetComponentCount(), 5u);
493  EXPECT_EQ(path.GetComponentCount(Path::ComponentType::kLinear), 3u);
494  EXPECT_EQ(path.GetComponentCount(Path::ComponentType::kContour), 2u);
495 }

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

◆ TEST() [226/389]

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

Definition at line 405 of file path_unittests.cc.

405  {
406  PathBuilder builder;
407 
408  auto path = builder.AddLine({0, 0}, {100, 100})
409  .AddQuadraticCurve({100, 100}, {200, 200}, {300, 300})
410  .AddCubicCurve({300, 300}, {400, 400}, {500, 500}, {600, 600})
411  .TakePath();
412 
413  EXPECT_EQ(path.GetComponentCount(), 6u);
414  EXPECT_EQ(path.GetComponentCount(Path::ComponentType::kLinear), 1u);
415  EXPECT_EQ(path.GetComponentCount(Path::ComponentType::kQuadratic), 1u);
416  EXPECT_EQ(path.GetComponentCount(Path::ComponentType::kCubic), 1u);
417  EXPECT_EQ(path.GetComponentCount(Path::ComponentType::kContour), 3u);
418 
419  {
420  LinearPathComponent linear;
421  EXPECT_TRUE(path.GetLinearComponentAtIndex(1, linear));
422 
423  Point p1(0, 0);
424  Point p2(100, 100);
425  EXPECT_EQ(linear.p1, p1);
426  EXPECT_EQ(linear.p2, p2);
427  }
428 
429  {
430  QuadraticPathComponent quad;
431  EXPECT_TRUE(path.GetQuadraticComponentAtIndex(3, quad));
432 
433  Point p1(100, 100);
434  Point cp(200, 200);
435  Point p2(300, 300);
436  EXPECT_EQ(quad.p1, p1);
437  EXPECT_EQ(quad.cp, cp);
438  EXPECT_EQ(quad.p2, p2);
439  }
440 
441  {
442  CubicPathComponent cubic;
443  EXPECT_TRUE(path.GetCubicComponentAtIndex(5, cubic));
444 
445  Point p1(300, 300);
446  Point cp1(400, 400);
447  Point cp2(500, 500);
448  Point p2(600, 600);
449  EXPECT_EQ(cubic.p1, p1);
450  EXPECT_EQ(cubic.cp1, cp1);
451  EXPECT_EQ(cubic.cp2, cp2);
452  EXPECT_EQ(cubic.p2, p2);
453  }
454 
455  {
456  ContourComponent contour;
457  EXPECT_TRUE(path.GetContourComponentAtIndex(0, contour));
458 
459  Point p1(0, 0);
460  EXPECT_EQ(contour.destination, p1);
461  EXPECT_FALSE(contour.IsClosed());
462  }
463 
464  {
465  ContourComponent contour;
466  EXPECT_TRUE(path.GetContourComponentAtIndex(2, contour));
467 
468  Point p1(100, 100);
469  EXPECT_EQ(contour.destination, p1);
470  EXPECT_FALSE(contour.IsClosed());
471  }
472 
473  {
474  ContourComponent contour;
475  EXPECT_TRUE(path.GetContourComponentAtIndex(4, contour));
476 
477  Point p1(300, 300);
478  EXPECT_EQ(contour.destination, p1);
479  EXPECT_FALSE(contour.IsClosed());
480  }
481 }

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

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

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

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

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

Definition at line 47 of file pool_unittests.cc.

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

◆ TEST() [231/389]

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

Definition at line 33 of file pool_unittests.cc.

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

◆ TEST() [232/389]

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

Definition at line 1302 of file rect_unittests.cc.

1302  {
1303  auto rect1 =
1304  Rect::MakeXYWH(472.599945f, 440.999969f, 1102.80005f, 654.000061f);
1305  auto rect2 = Rect::MakeXYWH(724.f, 618.f, 600.f, 300.f);
1306  EXPECT_TRUE(rect1.Contains(rect2));
1307 }

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

◆ TEST() [233/389]

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

Definition at line 885 of file rect_unittests.cc.

885  {
886  IRect rect = IRect::MakeLTRB(50, 50, 100, 100);
887 
888  auto test = [&rect](int64_t l, int64_t t, int64_t r, int64_t b,
889  const std::string& label) {
890  EXPECT_FALSE(IRect::MakeLTRB(l, b, r, t).IntersectsWithRect(rect))
891  << label << " with Top/Bottom swapped";
892  EXPECT_FALSE(IRect::MakeLTRB(r, b, l, t).IntersectsWithRect(rect))
893  << label << " with Left/Right swapped";
894  EXPECT_FALSE(IRect::MakeLTRB(r, t, l, b).IntersectsWithRect(rect))
895  << label << " with all sides swapped";
896  };
897 
898  test(20, 20, 30, 30, "Above and Left");
899  test(70, 20, 80, 30, "Above");
900  test(120, 20, 130, 30, "Above and Right");
901  test(120, 70, 130, 80, "Right");
902  test(120, 120, 130, 130, "Below and Right");
903  test(70, 120, 80, 130, "Below");
904  test(20, 120, 30, 130, "Below and Left");
905  test(20, 70, 30, 80, "Left");
906 
907  test(70, 70, 80, 80, "Inside");
908 
909  test(40, 70, 60, 80, "Straddling Left");
910  test(70, 40, 80, 60, "Straddling Top");
911  test(90, 70, 110, 80, "Straddling Right");
912  test(70, 90, 80, 110, "Straddling Bottom");
913 }

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

◆ TEST() [234/389]

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

Definition at line 855 of file rect_unittests.cc.

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

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

◆ TEST() [235/389]

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

Definition at line 1225 of file rect_unittests.cc.

1225  {
1226  EXPECT_EQ(Rect::MakeXYWH(10, 30, 20, 20).GetCenter(), Point(20, 40));
1227  EXPECT_EQ(Rect::MakeXYWH(10, 30, 20, 19).GetCenter(), Point(20, 39.5));
1228  EXPECT_EQ(Rect::MakeMaximum().GetCenter(), Point(0, 0));
1229 
1230  // Note that we expect a Point as the answer from an IRect
1231  EXPECT_EQ(IRect::MakeXYWH(10, 30, 20, 20).GetCenter(), Point(20, 40));
1232  EXPECT_EQ(IRect::MakeXYWH(10, 30, 20, 19).GetCenter(), Point(20, 39.5));
1233  EXPECT_EQ(IRect::MakeMaximum().GetCenter(), Point(0, 0));
1234 }

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

◆ TEST() [236/389]

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

Definition at line 1011 of file rect_unittests.cc.

1011  {
1012  EXPECT_EQ(IRect::MakeXYWH(0, 0, 100, 200).Area(), 20000);
1013  EXPECT_EQ(IRect::MakeXYWH(10, 20, 100, 200).Area(), 20000);
1014  EXPECT_EQ(IRect::MakeXYWH(0, 0, 200, 100).Area(), 20000);
1015  EXPECT_EQ(IRect::MakeXYWH(10, 20, 200, 100).Area(), 20000);
1016  EXPECT_EQ(IRect::MakeXYWH(0, 0, 100, 100).Area(), 10000);
1017  EXPECT_EQ(IRect::MakeXYWH(10, 20, 100, 100).Area(), 10000);
1018 }

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

◆ TEST() [237/389]

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

Definition at line 2398 of file rect_unittests.cc.

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

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

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

Definition at line 2236 of file rect_unittests.cc.

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

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

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

Definition at line 2589 of file rect_unittests.cc.

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

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

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

Definition at line 672 of file rect_unittests.cc.

672  {
673  IRect rect = IRect::MakeLTRB(5, 10, 20, 25);
674  IRect copy = rect;
675 
676  EXPECT_EQ(rect, copy);
677  EXPECT_EQ(copy.GetLeft(), 5);
678  EXPECT_EQ(copy.GetTop(), 10);
679  EXPECT_EQ(copy.GetRight(), 20);
680  EXPECT_EQ(copy.GetBottom(), 25);
681  EXPECT_EQ(copy.GetX(), 5);
682  EXPECT_EQ(copy.GetY(), 10);
683  EXPECT_EQ(copy.GetWidth(), 15);
684  EXPECT_EQ(copy.GetHeight(), 15);
685  EXPECT_FALSE(copy.IsEmpty());
686 }

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

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

Definition at line 2834 of file rect_unittests.cc.

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

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

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

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

Definition at line 825 of file rect_unittests.cc.

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

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

◆ TEST() [244/389]

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

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

Definition at line 1269 of file rect_unittests.cc.

1269  {
1270  auto rect = IRect::MakeLTRB(100, 100, 200, 200);
1271 
1272  // Expand(T amount)
1273  EXPECT_EQ(rect.Expand(10), IRect::MakeLTRB(90, 90, 210, 210));
1274  EXPECT_EQ(rect.Expand(-10), IRect::MakeLTRB(110, 110, 190, 190));
1275 
1276  // Expand(amount, amount)
1277  EXPECT_EQ(rect.Expand(10, 10), IRect::MakeLTRB(90, 90, 210, 210));
1278  EXPECT_EQ(rect.Expand(10, -10), IRect::MakeLTRB(90, 110, 210, 190));
1279  EXPECT_EQ(rect.Expand(-10, 10), IRect::MakeLTRB(110, 90, 190, 210));
1280  EXPECT_EQ(rect.Expand(-10, -10), IRect::MakeLTRB(110, 110, 190, 190));
1281 
1282  // Expand(amount, amount, amount, amount)
1283  EXPECT_EQ(rect.Expand(10, 20, 30, 40), IRect::MakeLTRB(90, 80, 230, 240));
1284  EXPECT_EQ(rect.Expand(-10, 20, 30, 40), IRect::MakeLTRB(110, 80, 230, 240));
1285  EXPECT_EQ(rect.Expand(10, -20, 30, 40), IRect::MakeLTRB(90, 120, 230, 240));
1286  EXPECT_EQ(rect.Expand(10, 20, -30, 40), IRect::MakeLTRB(90, 80, 170, 240));
1287  EXPECT_EQ(rect.Expand(10, 20, 30, -40), IRect::MakeLTRB(90, 80, 230, 160));
1288 
1289  // Expand(IPoint amount)
1290  EXPECT_EQ(rect.Expand(IPoint{10, 10}), IRect::MakeLTRB(90, 90, 210, 210));
1291  EXPECT_EQ(rect.Expand(IPoint{10, -10}), IRect::MakeLTRB(90, 110, 210, 190));
1292  EXPECT_EQ(rect.Expand(IPoint{-10, 10}), IRect::MakeLTRB(110, 90, 190, 210));
1293  EXPECT_EQ(rect.Expand(IPoint{-10, -10}), IRect::MakeLTRB(110, 110, 190, 190));
1294 
1295  // Expand(ISize amount)
1296  EXPECT_EQ(rect.Expand(ISize{10, 10}), IRect::MakeLTRB(90, 90, 210, 210));
1297  EXPECT_EQ(rect.Expand(ISize{10, -10}), IRect::MakeLTRB(90, 110, 210, 190));
1298  EXPECT_EQ(rect.Expand(ISize{-10, 10}), IRect::MakeLTRB(110, 90, 190, 210));
1299  EXPECT_EQ(rect.Expand(ISize{-10, -10}), IRect::MakeLTRB(110, 110, 190, 190));
1300 }

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

◆ TEST() [246/389]

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

Definition at line 647 of file rect_unittests.cc.

647  {
648  EXPECT_EQ(IRect(IRect::MakeXYWH(2, 3, 7, 15)), //
649  IRect::MakeXYWH(2, 3, 7, 15));
650  EXPECT_EQ(IRect(IRect::MakeLTRB(2, 3, 7, 15)), //
651  IRect::MakeLTRB(2, 3, 7, 15));
652 }

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

◆ TEST() [247/389]

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

Definition at line 1108 of file rect_unittests.cc.

1108  {
1109  {
1110  // Checks for expected matrix values
1111 
1112  auto r = IRect::MakeXYWH(100, 200, 200, 400);
1113 
1114  EXPECT_EQ(r.GetNormalizingTransform(),
1115  Matrix::MakeScale({0.005, 0.0025, 1.0}) *
1116  Matrix::MakeTranslation({-100, -200}));
1117  }
1118 
1119  {
1120  // Checks for expected transform of points relative to the rect
1121 
1122  auto r = IRect::MakeLTRB(300, 500, 400, 700);
1123  auto m = r.GetNormalizingTransform();
1124 
1125  // The 4 corners of the rect => (0, 0) to (1, 1)
1126  EXPECT_EQ(m * Point(300, 500), Point(0, 0));
1127  EXPECT_EQ(m * Point(400, 500), Point(1, 0));
1128  EXPECT_EQ(m * Point(400, 700), Point(1, 1));
1129  EXPECT_EQ(m * Point(300, 700), Point(0, 1));
1130 
1131  // The center => (0.5, 0.5)
1132  EXPECT_EQ(m * Point(350, 600), Point(0.5, 0.5));
1133 
1134  // Outside the 4 corners => (-1, -1) to (2, 2)
1135  EXPECT_EQ(m * Point(200, 300), Point(-1, -1));
1136  EXPECT_EQ(m * Point(500, 300), Point(2, -1));
1137  EXPECT_EQ(m * Point(500, 900), Point(2, 2));
1138  EXPECT_EQ(m * Point(200, 900), Point(-1, 2));
1139  }
1140 
1141  {
1142  // Checks for behavior with empty rects
1143 
1144  auto zero = Matrix::MakeScale({0.0, 0.0, 1.0});
1145 
1146  // Empty for width and/or height == 0
1147  EXPECT_EQ(IRect::MakeXYWH(10, 10, 0, 10).GetNormalizingTransform(), zero);
1148  EXPECT_EQ(IRect::MakeXYWH(10, 10, 10, 0).GetNormalizingTransform(), zero);
1149  EXPECT_EQ(IRect::MakeXYWH(10, 10, 0, 0).GetNormalizingTransform(), zero);
1150 
1151  // Empty for width and/or height < 0
1152  EXPECT_EQ(IRect::MakeXYWH(10, 10, -1, 10).GetNormalizingTransform(), zero);
1153  EXPECT_EQ(IRect::MakeXYWH(10, 10, 10, -1).GetNormalizingTransform(), zero);
1154  EXPECT_EQ(IRect::MakeXYWH(10, 10, -1, -1).GetNormalizingTransform(), zero);
1155  }
1156 }

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

◆ TEST() [248/389]

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

Definition at line 1794 of file rect_unittests.cc.

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

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

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

Definition at line 2059 of file rect_unittests.cc.

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

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

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

Definition at line 624 of file rect_unittests.cc.

624  {
625  IRect rect = IRect::MakeMaximum();
626  auto min = std::numeric_limits<int64_t>::min();
627  auto max = std::numeric_limits<int64_t>::max();
628 
629  EXPECT_EQ(rect.GetLeft(), min);
630  EXPECT_EQ(rect.GetTop(), min);
631  EXPECT_EQ(rect.GetRight(), max);
632  EXPECT_EQ(rect.GetBottom(), max);
633  EXPECT_EQ(rect.GetX(), min);
634  EXPECT_EQ(rect.GetY(), min);
635  EXPECT_EQ(rect.GetWidth(), max);
636  EXPECT_EQ(rect.GetHeight(), max);
637  EXPECT_FALSE(rect.IsEmpty());
638 }

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

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

Definition at line 714 of file rect_unittests.cc.

714  {
715  {
716  IRect r = IRect::MakeOriginSize({10, 20}, {50, 40});
717  EXPECT_EQ(r.GetOrigin(), IPoint(10, 20));
718  EXPECT_EQ(r.GetSize(), ISize(50, 40));
719  EXPECT_EQ(r.GetX(), 10);
720  EXPECT_EQ(r.GetY(), 20);
721  EXPECT_EQ(r.GetWidth(), 50);
722  EXPECT_EQ(r.GetHeight(), 40);
723  auto expected_array = std::array<int64_t, 4>{10, 20, 50, 40};
724  EXPECT_EQ(r.GetXYWH(), expected_array);
725  }
726 
727  {
728  IRect r = IRect::MakeLTRB(10, 20, 50, 40);
729  EXPECT_EQ(r.GetOrigin(), IPoint(10, 20));
730  EXPECT_EQ(r.GetSize(), ISize(40, 20));
731  EXPECT_EQ(r.GetX(), 10);
732  EXPECT_EQ(r.GetY(), 20);
733  EXPECT_EQ(r.GetWidth(), 40);
734  EXPECT_EQ(r.GetHeight(), 20);
735  auto expected_array = std::array<int64_t, 4>{10, 20, 40, 20};
736  EXPECT_EQ(r.GetXYWH(), expected_array);
737  }
738 }

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

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

Definition at line 509 of file rect_unittests.cc.

509  {
510  auto min = std::numeric_limits<int64_t>::min();
511  auto max = std::numeric_limits<int64_t>::max();
512 
513  // 4 cases
514  // negative l, r near max takes width past max
515  // positive l, r near min takes width below min
516  // negative t, b near max takes width past max
517  // positive t, b near min takes width below min
518 
519  {
520  IRect rect = IRect::MakeLTRB(-10, 10, max - 5, 26);
521 
522  EXPECT_EQ(rect.GetLeft(), -10);
523  EXPECT_EQ(rect.GetTop(), 10);
524  EXPECT_EQ(rect.GetRight(), max - 5);
525  EXPECT_EQ(rect.GetBottom(), 26);
526  EXPECT_EQ(rect.GetX(), -10);
527  EXPECT_EQ(rect.GetY(), 10);
528  EXPECT_EQ(rect.GetWidth(), max);
529  EXPECT_EQ(rect.GetHeight(), 16);
530  EXPECT_FALSE(rect.IsEmpty());
531  }
532 
533  {
534  IRect rect = IRect::MakeLTRB(10, 10, min + 5, 26);
535 
536  EXPECT_EQ(rect.GetLeft(), 10);
537  EXPECT_EQ(rect.GetTop(), 10);
538  EXPECT_EQ(rect.GetRight(), min + 5);
539  EXPECT_EQ(rect.GetBottom(), 26);
540  EXPECT_EQ(rect.GetX(), 10);
541  EXPECT_EQ(rect.GetY(), 10);
542  EXPECT_EQ(rect.GetWidth(), min);
543  EXPECT_EQ(rect.GetHeight(), 16);
544  EXPECT_TRUE(rect.IsEmpty());
545  }
546 
547  {
548  IRect rect = IRect::MakeLTRB(5, -10, 15, max - 5);
549 
550  EXPECT_EQ(rect.GetLeft(), 5);
551  EXPECT_EQ(rect.GetTop(), -10);
552  EXPECT_EQ(rect.GetRight(), 15);
553  EXPECT_EQ(rect.GetBottom(), max - 5);
554  EXPECT_EQ(rect.GetX(), 5);
555  EXPECT_EQ(rect.GetY(), -10);
556  EXPECT_EQ(rect.GetWidth(), 10);
557  EXPECT_EQ(rect.GetHeight(), max);
558  EXPECT_FALSE(rect.IsEmpty());
559  }
560 
561  {
562  IRect rect = IRect::MakeLTRB(5, 10, 15, min + 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(), min + 5);
568  EXPECT_EQ(rect.GetX(), 5);
569  EXPECT_EQ(rect.GetY(), 10);
570  EXPECT_EQ(rect.GetWidth(), 10);
571  EXPECT_EQ(rect.GetHeight(), min);
572  EXPECT_TRUE(rect.IsEmpty());
573  }
574 }

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

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

Definition at line 303 of file rect_unittests.cc.

303  {
304  auto min = std::numeric_limits<int64_t>::min();
305  auto max = std::numeric_limits<int64_t>::max();
306 
307  // 4 cases
308  // x near max, positive w takes it past max
309  // x near min, negative w takes it below min
310  // y near max, positive h takes it past max
311  // y near min, negative h takes it below min
312 
313  {
314  IRect rect = IRect::MakeXYWH(max - 5, 10, 10, 16);
315 
316  EXPECT_EQ(rect.GetLeft(), max - 5);
317  EXPECT_EQ(rect.GetTop(), 10);
318  EXPECT_EQ(rect.GetRight(), max);
319  EXPECT_EQ(rect.GetBottom(), 26);
320  EXPECT_EQ(rect.GetX(), max - 5);
321  EXPECT_EQ(rect.GetY(), 10);
322  EXPECT_EQ(rect.GetWidth(), 5);
323  EXPECT_EQ(rect.GetHeight(), 16);
324  EXPECT_FALSE(rect.IsEmpty());
325  }
326 
327  {
328  IRect rect = IRect::MakeXYWH(min + 5, 10, -10, 16);
329 
330  EXPECT_EQ(rect.GetLeft(), min + 5);
331  EXPECT_EQ(rect.GetTop(), 10);
332  EXPECT_EQ(rect.GetRight(), min);
333  EXPECT_EQ(rect.GetBottom(), 26);
334  EXPECT_EQ(rect.GetX(), min + 5);
335  EXPECT_EQ(rect.GetY(), 10);
336  EXPECT_EQ(rect.GetWidth(), -5);
337  EXPECT_EQ(rect.GetHeight(), 16);
338  EXPECT_TRUE(rect.IsEmpty());
339  }
340 
341  {
342  IRect rect = IRect::MakeXYWH(5, max - 10, 10, 16);
343 
344  EXPECT_EQ(rect.GetLeft(), 5);
345  EXPECT_EQ(rect.GetTop(), max - 10);
346  EXPECT_EQ(rect.GetRight(), 15);
347  EXPECT_EQ(rect.GetBottom(), max);
348  EXPECT_EQ(rect.GetX(), 5);
349  EXPECT_EQ(rect.GetY(), max - 10);
350  EXPECT_EQ(rect.GetWidth(), 10);
351  EXPECT_EQ(rect.GetHeight(), 10);
352  EXPECT_FALSE(rect.IsEmpty());
353  }
354 
355  {
356  IRect rect = IRect::MakeXYWH(5, min + 10, 10, -16);
357 
358  EXPECT_EQ(rect.GetLeft(), 5);
359  EXPECT_EQ(rect.GetTop(), min + 10);
360  EXPECT_EQ(rect.GetRight(), 15);
361  EXPECT_EQ(rect.GetBottom(), min);
362  EXPECT_EQ(rect.GetX(), 5);
363  EXPECT_EQ(rect.GetY(), min + 10);
364  EXPECT_EQ(rect.GetWidth(), 10);
365  EXPECT_EQ(rect.GetHeight(), -10);
366  EXPECT_TRUE(rect.IsEmpty());
367  }
368 }

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

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

Definition at line 3092 of file rect_unittests.cc.

3092  {
3093  {
3094  auto r = Rect::MakeLTRB(-100, -200, 300, 400);
3095  auto ir = IRect::MakeLTRB(-100, -200, 300, 400);
3096  EXPECT_EQ(IRect::Round(r), ir);
3097  }
3098  {
3099  auto r = Rect::MakeLTRB(-100.4, -200.4, 300.4, 400.4);
3100  auto ir = IRect::MakeLTRB(-100, -200, 300, 400);
3101  EXPECT_EQ(IRect::Round(r), ir);
3102  }
3103  {
3104  auto r = Rect::MakeLTRB(-100.5, -200.5, 300.5, 400.5);
3105  auto ir = IRect::MakeLTRB(-101, -201, 301, 401);
3106  EXPECT_EQ(IRect::Round(r), ir);
3107  }
3108 }

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

◆ TEST() [255/389]

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

Definition at line 3064 of file rect_unittests.cc.

3064  {
3065  {
3066  auto r = Rect::MakeLTRB(-100, -200, 300, 400);
3067  auto ir = IRect::MakeLTRB(-100, -200, 300, 400);
3068  EXPECT_EQ(IRect::RoundOut(r), ir);
3069  }
3070  {
3071  auto r = Rect::MakeLTRB(-100.1, -200.1, 300.1, 400.1);
3072  auto ir = IRect::MakeLTRB(-101, -201, 301, 401);
3073  EXPECT_EQ(IRect::RoundOut(r), ir);
3074  }
3075 }

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

◆ TEST() [256/389]

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

Definition at line 960 of file rect_unittests.cc.

960  {
961  auto test1 = [](IRect rect, int64_t scale) {
962  IRect expected = IRect::MakeXYWH(rect.GetX() * scale, //
963  rect.GetY() * scale, //
964  rect.GetWidth() * scale, //
965  rect.GetHeight() * scale);
966 
967  EXPECT_EQ(rect.Scale(scale), expected) //
968  << rect << " * " << scale;
969  EXPECT_EQ(rect.Scale(scale, scale), expected) //
970  << rect << " * " << scale;
971  EXPECT_EQ(rect.Scale(IPoint(scale, scale)), expected) //
972  << rect << " * " << scale;
973  EXPECT_EQ(rect.Scale(ISize(scale, scale)), expected) //
974  << rect << " * " << scale;
975  };
976 
977  auto test2 = [&test1](IRect rect, int64_t scale_x, int64_t scale_y) {
978  IRect expected = IRect::MakeXYWH(rect.GetX() * scale_x, //
979  rect.GetY() * scale_y, //
980  rect.GetWidth() * scale_x, //
981  rect.GetHeight() * scale_y);
982 
983  EXPECT_EQ(rect.Scale(scale_x, scale_y), expected) //
984  << rect << " * " << scale_x << ", " << scale_y;
985  EXPECT_EQ(rect.Scale(IPoint(scale_x, scale_y)), expected) //
986  << rect << " * " << scale_x << ", " << scale_y;
987  EXPECT_EQ(rect.Scale(ISize(scale_x, scale_y)), expected) //
988  << rect << " * " << scale_x << ", " << scale_y;
989 
990  test1(rect, scale_x);
991  test1(rect, scale_y);
992  };
993 
994  test2(IRect::MakeLTRB(10, 15, 100, 150), 2, 3);
995  test2(IRect::MakeLTRB(10, 15, 100, 150), 3, 2);
996  test2(IRect::MakeLTRB(10, 15, -100, 150), 2, 3);
997  test2(IRect::MakeLTRB(10, 15, 100, -150), 2, 3);
998  test2(IRect::MakeLTRB(10, 15, 100, 150), -2, 3);
999  test2(IRect::MakeLTRB(10, 15, 100, 150), 2, -3);
1000 }

References impeller::TRect< T >::GetHeight(), impeller::TRect< T >::GetWidth(), impeller::TRect< T >::GetX(), impeller::TRect< T >::GetY(), impeller::TRect< T >::MakeLTRB(), impeller::TRect< T >::MakeXYWH(), impeller::TRect< T >::Scale(), and scale.

◆ TEST() [257/389]

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

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

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

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

Definition at line 1487 of file rect_unittests.cc.

1487  {
1488  auto check_empty_flips = [](const IRect& a, const IRect& b,
1489  const std::string& label) {
1490  ASSERT_FALSE(a.IsEmpty());
1491  // b is allowed to be empty
1492 
1493  // unflipped a vs flipped (empty) b yields a
1494  EXPECT_EQ(a.Union(flip_lr(b)), a) << label;
1495  EXPECT_EQ(a.Union(flip_tb(b)), a) << label;
1496  EXPECT_EQ(a.Union(flip_lrtb(b)), a) << label;
1497 
1498  // flipped (empty) a vs unflipped b yields b
1499  EXPECT_EQ(flip_lr(a).Union(b), b) << label;
1500  EXPECT_EQ(flip_tb(a).Union(b), b) << label;
1501  EXPECT_EQ(flip_lrtb(a).Union(b), b) << label;
1502 
1503  // flipped (empty) a vs flipped (empty) b yields empty
1504  EXPECT_TRUE(flip_lr(a).Union(flip_lr(b)).IsEmpty()) << label;
1505  EXPECT_TRUE(flip_tb(a).Union(flip_tb(b)).IsEmpty()) << label;
1506  EXPECT_TRUE(flip_lrtb(a).Union(flip_lrtb(b)).IsEmpty()) << label;
1507  };
1508 
1509  auto test = [&check_empty_flips](const IRect& a, const IRect& b,
1510  const IRect& result) {
1511  ASSERT_FALSE(a.IsEmpty()) << a;
1512  // b is allowed to be empty
1513 
1514  std::stringstream stream;
1515  stream << a << " union " << b;
1516  auto label = stream.str();
1517 
1518  EXPECT_EQ(a.Union(b), result) << label;
1519  EXPECT_EQ(b.Union(a), result) << label;
1520  check_empty_flips(a, b, label);
1521  };
1522 
1523  {
1524  auto a = IRect::MakeXYWH(100, 100, 100, 100);
1525  auto b = IRect::MakeXYWH(0, 0, 0, 0);
1526  auto expected = IRect::MakeXYWH(100, 100, 100, 100);
1527  test(a, b, expected);
1528  }
1529 
1530  {
1531  auto a = IRect::MakeXYWH(100, 100, 100, 100);
1532  auto b = IRect::MakeXYWH(0, 0, 1, 1);
1533  auto expected = IRect::MakeXYWH(0, 0, 200, 200);
1534  test(a, b, expected);
1535  }
1536 
1537  {
1538  auto a = IRect::MakeXYWH(100, 100, 100, 100);
1539  auto b = IRect::MakeXYWH(10, 10, 1, 1);
1540  auto expected = IRect::MakeXYWH(10, 10, 190, 190);
1541  test(a, b, expected);
1542  }
1543 
1544  {
1545  auto a = IRect::MakeXYWH(0, 0, 100, 100);
1546  auto b = IRect::MakeXYWH(10, 10, 100, 100);
1547  auto expected = IRect::MakeXYWH(0, 0, 110, 110);
1548  test(a, b, expected);
1549  }
1550 
1551  {
1552  auto a = IRect::MakeXYWH(0, 0, 100, 100);
1553  auto b = IRect::MakeXYWH(100, 100, 100, 100);
1554  auto expected = IRect::MakeXYWH(0, 0, 200, 200);
1555  test(a, b, expected);
1556  }
1557 }

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

◆ TEST() [261/389]

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

Definition at line 1182 of file rect_unittests.cc.

1182  {
1183  // Non-empty
1184  EXPECT_FALSE(IRect::MakeXYWH(1, 2, 10, 7).IsEmpty());
1185 
1186  // Empty both width and height both 0 or negative, in all combinations
1187  EXPECT_TRUE(IRect::MakeXYWH(1, 2, 0, 0).IsEmpty());
1188  EXPECT_TRUE(IRect::MakeXYWH(1, 2, -1, -1).IsEmpty());
1189  EXPECT_TRUE(IRect::MakeXYWH(1, 2, -1, 0).IsEmpty());
1190  EXPECT_TRUE(IRect::MakeXYWH(1, 2, 0, -1).IsEmpty());
1191 
1192  // Empty for 0 or negative width or height (but not both at the same time)
1193  EXPECT_TRUE(IRect::MakeXYWH(1, 2, 10, 0).IsEmpty());
1194  EXPECT_TRUE(IRect::MakeXYWH(1, 2, 10, -1).IsEmpty());
1195  EXPECT_TRUE(IRect::MakeXYWH(1, 2, 0, 7).IsEmpty());
1196  EXPECT_TRUE(IRect::MakeXYWH(1, 2, -1, 7).IsEmpty());
1197 }

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

◆ TEST() [262/389]

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

Definition at line 1213 of file rect_unittests.cc.

1213  {
1214  EXPECT_TRUE(Rect::MakeXYWH(10, 30, 20, 20).IsSquare());
1215  EXPECT_FALSE(Rect::MakeXYWH(10, 30, 20, 19).IsSquare());
1216  EXPECT_FALSE(Rect::MakeXYWH(10, 30, 19, 20).IsSquare());
1217  EXPECT_TRUE(Rect::MakeMaximum().IsSquare());
1218 
1219  EXPECT_TRUE(IRect::MakeXYWH(10, 30, 20, 20).IsSquare());
1220  EXPECT_FALSE(IRect::MakeXYWH(10, 30, 20, 19).IsSquare());
1221  EXPECT_FALSE(IRect::MakeXYWH(10, 30, 19, 20).IsSquare());
1222  EXPECT_TRUE(IRect::MakeMaximum().IsSquare());
1223 }

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

◆ TEST() [263/389]

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

Definition at line 1199 of file rect_unittests.cc.

1199  {
1200  Quad quad = {
1201  Point(10, 10),
1202  Point(20, 10),
1203  Point(10, 20),
1204  Point(20, 20),
1205  };
1206  std::optional<Rect> bounds = Rect::MakePointBounds(quad);
1207  EXPECT_TRUE(bounds.has_value());
1208  if (bounds.has_value()) {
1209  EXPECT_TRUE(RectNear(bounds.value(), Rect::MakeLTRB(10, 10, 20, 20)));
1210  }
1211 }

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

◆ TEST() [264/389]

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

Definition at line 1889 of file rect_unittests.cc.

1889  {
1890  auto a = IRect::MakeLTRB(0, 0, 110, 110);
1891  auto b = IRect::MakeLTRB(100, 100, 200, 200);
1892  auto c = IRect::MakeLTRB(100, 0, 200, 110);
1893 
1894  // NullOpt, NullOpt
1895  EXPECT_FALSE(IRect::Intersection(std::nullopt, std::nullopt).has_value());
1896  EXPECT_EQ(IRect::Intersection(std::nullopt, std::nullopt), std::nullopt);
1897 
1898  auto test1 = [](const IRect& r) {
1899  // Rect, NullOpt
1900  EXPECT_TRUE(IRect::Intersection(r, std::nullopt).has_value());
1901  EXPECT_EQ(IRect::Intersection(r, std::nullopt).value(), r);
1902 
1903  // OptRect, NullOpt
1904  EXPECT_TRUE(
1905  IRect::Intersection(std::optional(r), std::nullopt).has_value());
1906  EXPECT_EQ(IRect::Intersection(std::optional(r), std::nullopt).value(), r);
1907 
1908  // NullOpt, Rect
1909  EXPECT_TRUE(IRect::Intersection(std::nullopt, r).has_value());
1910  EXPECT_EQ(IRect::Intersection(std::nullopt, r).value(), r);
1911 
1912  // NullOpt, OptRect
1913  EXPECT_TRUE(
1914  IRect::Intersection(std::nullopt, std::optional(r)).has_value());
1915  EXPECT_EQ(IRect::Intersection(std::nullopt, std::optional(r)).value(), r);
1916  };
1917 
1918  test1(a);
1919  test1(b);
1920  test1(c);
1921 
1922  auto test2 = [](const IRect& a, const IRect& b, const IRect& i) {
1923  ASSERT_EQ(a.Intersection(b), i);
1924 
1925  // Rect, OptRect
1926  EXPECT_TRUE(IRect::Intersection(a, std::optional(b)).has_value());
1927  EXPECT_EQ(IRect::Intersection(a, std::optional(b)).value(), i);
1928 
1929  // OptRect, Rect
1930  EXPECT_TRUE(IRect::Intersection(std::optional(a), b).has_value());
1931  EXPECT_EQ(IRect::Intersection(std::optional(a), b).value(), i);
1932 
1933  // OptRect, OptRect
1934  EXPECT_TRUE(
1935  IRect::Intersection(std::optional(a), std::optional(b)).has_value());
1936  EXPECT_EQ(IRect::Intersection(std::optional(a), std::optional(b)).value(),
1937  i);
1938  };
1939 
1940  test2(a, b, IRect::MakeLTRB(100, 100, 110, 110));
1941  test2(a, c, IRect::MakeLTRB(100, 0, 110, 110));
1942  test2(b, c, IRect::MakeLTRB(100, 100, 200, 110));
1943 }

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

◆ TEST() [265/389]

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

Definition at line 1559 of file rect_unittests.cc.

1559  {
1560  auto a = IRect::MakeLTRB(0, 0, 100, 100);
1561  auto b = IRect::MakeLTRB(100, 100, 200, 200);
1562  auto c = IRect::MakeLTRB(100, 0, 200, 100);
1563 
1564  // NullOpt, NullOpt
1565  EXPECT_FALSE(IRect::Union(std::nullopt, std::nullopt).has_value());
1566  EXPECT_EQ(IRect::Union(std::nullopt, std::nullopt), std::nullopt);
1567 
1568  auto test1 = [](const IRect& r) {
1569  // Rect, NullOpt
1570  EXPECT_TRUE(IRect::Union(r, std::nullopt).has_value());
1571  EXPECT_EQ(IRect::Union(r, std::nullopt).value(), r);
1572 
1573  // OptRect, NullOpt
1574  EXPECT_TRUE(IRect::Union(std::optional(r), std::nullopt).has_value());
1575  EXPECT_EQ(IRect::Union(std::optional(r), std::nullopt).value(), r);
1576 
1577  // NullOpt, Rect
1578  EXPECT_TRUE(IRect::Union(std::nullopt, r).has_value());
1579  EXPECT_EQ(IRect::Union(std::nullopt, r).value(), r);
1580 
1581  // NullOpt, OptRect
1582  EXPECT_TRUE(IRect::Union(std::nullopt, std::optional(r)).has_value());
1583  EXPECT_EQ(IRect::Union(std::nullopt, std::optional(r)).value(), r);
1584  };
1585 
1586  test1(a);
1587  test1(b);
1588  test1(c);
1589 
1590  auto test2 = [](const IRect& a, const IRect& b, const IRect& u) {
1591  ASSERT_EQ(a.Union(b), u);
1592 
1593  // Rect, OptRect
1594  EXPECT_TRUE(IRect::Union(a, std::optional(b)).has_value());
1595  EXPECT_EQ(IRect::Union(a, std::optional(b)).value(), u);
1596 
1597  // OptRect, Rect
1598  EXPECT_TRUE(IRect::Union(std::optional(a), b).has_value());
1599  EXPECT_EQ(IRect::Union(std::optional(a), b).value(), u);
1600 
1601  // OptRect, OptRect
1602  EXPECT_TRUE(IRect::Union(std::optional(a), std::optional(b)).has_value());
1603  EXPECT_EQ(IRect::Union(std::optional(a), std::optional(b)).value(), u);
1604  };
1605 
1606  test2(a, b, IRect::MakeLTRB(0, 0, 200, 200));
1607  test2(a, c, IRect::MakeLTRB(0, 0, 200, 100));
1608  test2(b, c, IRect::MakeLTRB(100, 0, 200, 200));
1609 }

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

◆ TEST() [266/389]

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

Definition at line 1740 of file rect_unittests.cc.

1740  {
1741  auto a = Rect::MakeLTRB(0, 0, 110, 110);
1742  auto b = Rect::MakeLTRB(100, 100, 200, 200);
1743  auto c = Rect::MakeLTRB(100, 0, 200, 110);
1744 
1745  // NullOpt, NullOpt
1746  EXPECT_FALSE(Rect::Intersection(std::nullopt, std::nullopt).has_value());
1747  EXPECT_EQ(Rect::Intersection(std::nullopt, std::nullopt), std::nullopt);
1748 
1749  auto test1 = [](const Rect& r) {
1750  // Rect, NullOpt
1751  EXPECT_TRUE(Rect::Intersection(r, std::nullopt).has_value());
1752  EXPECT_EQ(Rect::Intersection(r, std::nullopt).value(), r);
1753 
1754  // OptRect, NullOpt
1755  EXPECT_TRUE(Rect::Intersection(std::optional(r), std::nullopt).has_value());
1756  EXPECT_EQ(Rect::Intersection(std::optional(r), std::nullopt).value(), r);
1757 
1758  // NullOpt, Rect
1759  EXPECT_TRUE(Rect::Intersection(std::nullopt, r).has_value());
1760  EXPECT_EQ(Rect::Intersection(std::nullopt, r).value(), r);
1761 
1762  // NullOpt, OptRect
1763  EXPECT_TRUE(Rect::Intersection(std::nullopt, std::optional(r)).has_value());
1764  EXPECT_EQ(Rect::Intersection(std::nullopt, std::optional(r)).value(), r);
1765  };
1766 
1767  test1(a);
1768  test1(b);
1769  test1(c);
1770 
1771  auto test2 = [](const Rect& a, const Rect& b, const Rect& i) {
1772  ASSERT_EQ(a.Intersection(b), i);
1773 
1774  // Rect, OptRect
1775  EXPECT_TRUE(Rect::Intersection(a, std::optional(b)).has_value());
1776  EXPECT_EQ(Rect::Intersection(a, std::optional(b)).value(), i);
1777 
1778  // OptRect, Rect
1779  EXPECT_TRUE(Rect::Intersection(std::optional(a), b).has_value());
1780  EXPECT_EQ(Rect::Intersection(std::optional(a), b).value(), i);
1781 
1782  // OptRect, OptRect
1783  EXPECT_TRUE(
1784  Rect::Intersection(std::optional(a), std::optional(b)).has_value());
1785  EXPECT_EQ(Rect::Intersection(std::optional(a), std::optional(b)).value(),
1786  i);
1787  };
1788 
1789  test2(a, b, Rect::MakeLTRB(100, 100, 110, 110));
1790  test2(a, c, Rect::MakeLTRB(100, 0, 110, 110));
1791  test2(b, c, Rect::MakeLTRB(100, 100, 200, 110));
1792 }

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

◆ TEST() [267/389]

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

Definition at line 1435 of file rect_unittests.cc.

1435  {
1436  auto a = Rect::MakeLTRB(0, 0, 100, 100);
1437  auto b = Rect::MakeLTRB(100, 100, 200, 200);
1438  auto c = Rect::MakeLTRB(100, 0, 200, 100);
1439 
1440  // NullOpt, NullOpt
1441  EXPECT_FALSE(Rect::Union(std::nullopt, std::nullopt).has_value());
1442  EXPECT_EQ(Rect::Union(std::nullopt, std::nullopt), std::nullopt);
1443 
1444  auto test1 = [](const Rect& r) {
1445  // Rect, NullOpt
1446  EXPECT_TRUE(Rect::Union(r, std::nullopt).has_value());
1447  EXPECT_EQ(Rect::Union(r, std::nullopt).value(), r);
1448 
1449  // OptRect, NullOpt
1450  EXPECT_TRUE(Rect::Union(std::optional(r), std::nullopt).has_value());
1451  EXPECT_EQ(Rect::Union(std::optional(r), std::nullopt).value(), r);
1452 
1453  // NullOpt, Rect
1454  EXPECT_TRUE(Rect::Union(std::nullopt, r).has_value());
1455  EXPECT_EQ(Rect::Union(std::nullopt, r).value(), r);
1456 
1457  // NullOpt, OptRect
1458  EXPECT_TRUE(Rect::Union(std::nullopt, std::optional(r)).has_value());
1459  EXPECT_EQ(Rect::Union(std::nullopt, std::optional(r)).value(), r);
1460  };
1461 
1462  test1(a);
1463  test1(b);
1464  test1(c);
1465 
1466  auto test2 = [](const Rect& a, const Rect& b, const Rect& u) {
1467  ASSERT_EQ(a.Union(b), u);
1468 
1469  // Rect, OptRect
1470  EXPECT_TRUE(Rect::Union(a, std::optional(b)).has_value());
1471  EXPECT_EQ(Rect::Union(a, std::optional(b)).value(), u);
1472 
1473  // OptRect, Rect
1474  EXPECT_TRUE(Rect::Union(std::optional(a), b).has_value());
1475  EXPECT_EQ(Rect::Union(std::optional(a), b).value(), u);
1476 
1477  // OptRect, OptRect
1478  EXPECT_TRUE(Rect::Union(std::optional(a), std::optional(b)).has_value());
1479  EXPECT_EQ(Rect::Union(std::optional(a), std::optional(b)).value(), u);
1480  };
1481 
1482  test2(a, b, Rect::MakeLTRB(0, 0, 200, 200));
1483  test2(a, c, Rect::MakeLTRB(0, 0, 200, 100));
1484  test2(b, c, Rect::MakeLTRB(100, 0, 200, 200));
1485 }

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

◆ TEST() [268/389]

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

Definition at line 1002 of file rect_unittests.cc.

1002  {
1003  EXPECT_EQ(Rect::MakeXYWH(0, 0, 100, 200).Area(), 20000);
1004  EXPECT_EQ(Rect::MakeXYWH(10, 20, 100, 200).Area(), 20000);
1005  EXPECT_EQ(Rect::MakeXYWH(0, 0, 200, 100).Area(), 20000);
1006  EXPECT_EQ(Rect::MakeXYWH(10, 20, 200, 100).Area(), 20000);
1007  EXPECT_EQ(Rect::MakeXYWH(0, 0, 100, 100).Area(), 10000);
1008  EXPECT_EQ(Rect::MakeXYWH(10, 20, 100, 100).Area(), 10000);
1009 }

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

◆ TEST() [269/389]

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

Definition at line 2305 of file rect_unittests.cc.

2305  {
2306  auto check_nans = [](const Rect& rect, const Point& point,
2307  const std::string& label) {
2308  ASSERT_TRUE(rect.IsFinite()) << label;
2309  ASSERT_TRUE(point.IsFinite()) << label;
2310 
2311  for (int i = 1; i < 16; i++) {
2312  EXPECT_FALSE(swap_nan(rect, i).ContainsInclusive(point))
2313  << label << ", index = " << i;
2314  for (int j = 1; j < 4; j++) {
2315  EXPECT_FALSE(swap_nan(rect, i).ContainsInclusive(swap_nan(point, j)))
2316  << label << ", indices = " << i << ", " << j;
2317  }
2318  }
2319  };
2320 
2321  auto check_empty_flips = [](const Rect& rect, const Point& point,
2322  const std::string& label) {
2323  ASSERT_FALSE(rect.IsEmpty());
2324 
2325  EXPECT_FALSE(flip_lr(rect).ContainsInclusive(point)) << label;
2326  EXPECT_FALSE(flip_tb(rect).ContainsInclusive(point)) << label;
2327  EXPECT_FALSE(flip_lrtb(rect).ContainsInclusive(point)) << label;
2328  };
2329 
2330  auto test_inside = [&check_nans, &check_empty_flips](const Rect& rect,
2331  const Point& point) {
2332  ASSERT_FALSE(rect.IsEmpty()) << rect;
2333 
2334  std::stringstream stream;
2335  stream << rect << " contains " << point;
2336  auto label = stream.str();
2337 
2338  EXPECT_TRUE(rect.ContainsInclusive(point)) << label;
2339  check_empty_flips(rect, point, label);
2340  check_nans(rect, point, label);
2341  };
2342 
2343  auto test_outside = [&check_nans, &check_empty_flips](const Rect& rect,
2344  const Point& point) {
2345  ASSERT_FALSE(rect.IsEmpty()) << rect;
2346 
2347  std::stringstream stream;
2348  stream << rect << " contains " << point;
2349  auto label = stream.str();
2350 
2351  EXPECT_FALSE(rect.ContainsInclusive(point)) << label;
2352  check_empty_flips(rect, point, label);
2353  check_nans(rect, point, label);
2354  };
2355 
2356  {
2357  // Origin is inclusive
2358  auto r = Rect::MakeXYWH(100, 100, 100, 100);
2359  auto p = Point(100, 100);
2360 
2361  test_inside(r, p);
2362  }
2363  {
2364  // Size is inclusive
2365  auto r = Rect::MakeXYWH(100, 100, 100, 100);
2366  auto p = Point(200, 200);
2367 
2368  test_inside(r, p);
2369  }
2370  {
2371  // Size + epsilon is exclusive
2372  auto r = Rect::MakeXYWH(100, 100, 100, 100);
2373  auto p = Point(200 + kEhCloseEnough, 200 + kEhCloseEnough);
2374 
2375  test_outside(r, p);
2376  }
2377  {
2378  auto r = Rect::MakeXYWH(100, 100, 100, 100);
2379  auto p = Point(99, 99);
2380 
2381  test_outside(r, p);
2382  }
2383  {
2384  auto r = Rect::MakeXYWH(100, 100, 100, 100);
2385  auto p = Point(199, 199);
2386 
2387  test_inside(r, p);
2388  }
2389 
2390  {
2391  auto r = Rect::MakeMaximum();
2392  auto p = Point(199, 199);
2393 
2394  test_inside(r, p);
2395  }
2396 }

References flip_lr(), flip_lrtb(), flip_tb(), impeller::TRect< T >::IsEmpty(), impeller::TRect< T >::IsFinite(), impeller::kEhCloseEnough, impeller::TRect< Scalar >::MakeMaximum(), impeller::TRect< Scalar >::MakeXYWH(), and swap_nan().

◆ TEST() [270/389]

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

Definition at line 2150 of file rect_unittests.cc.

2150  {
2151  auto check_nans = [](const Rect& rect, const Point& point,
2152  const std::string& label) {
2153  ASSERT_TRUE(rect.IsFinite()) << label;
2154  ASSERT_TRUE(point.IsFinite()) << label;
2155 
2156  for (int i = 1; i < 16; i++) {
2157  EXPECT_FALSE(swap_nan(rect, i).Contains(point))
2158  << label << ", index = " << i;
2159  for (int j = 1; j < 4; j++) {
2160  EXPECT_FALSE(swap_nan(rect, i).Contains(swap_nan(point, j)))
2161  << label << ", indices = " << i << ", " << j;
2162  }
2163  }
2164  };
2165 
2166  auto check_empty_flips = [](const Rect& rect, const Point& point,
2167  const std::string& label) {
2168  ASSERT_FALSE(rect.IsEmpty());
2169 
2170  EXPECT_FALSE(flip_lr(rect).Contains(point)) << label;
2171  EXPECT_FALSE(flip_tb(rect).Contains(point)) << label;
2172  EXPECT_FALSE(flip_lrtb(rect).Contains(point)) << label;
2173  };
2174 
2175  auto test_inside = [&check_nans, &check_empty_flips](const Rect& rect,
2176  const Point& point) {
2177  ASSERT_FALSE(rect.IsEmpty()) << rect;
2178 
2179  std::stringstream stream;
2180  stream << rect << " contains " << point;
2181  auto label = stream.str();
2182 
2183  EXPECT_TRUE(rect.Contains(point)) << label;
2184  check_empty_flips(rect, point, label);
2185  check_nans(rect, point, label);
2186  };
2187 
2188  auto test_outside = [&check_nans, &check_empty_flips](const Rect& rect,
2189  const Point& point) {
2190  ASSERT_FALSE(rect.IsEmpty()) << rect;
2191 
2192  std::stringstream stream;
2193  stream << rect << " contains " << point;
2194  auto label = stream.str();
2195 
2196  EXPECT_FALSE(rect.Contains(point)) << label;
2197  check_empty_flips(rect, point, label);
2198  check_nans(rect, point, label);
2199  };
2200 
2201  {
2202  // Origin is inclusive
2203  auto r = Rect::MakeXYWH(100, 100, 100, 100);
2204  auto p = Point(100, 100);
2205 
2206  test_inside(r, p);
2207  }
2208  {
2209  // Size is exclusive
2210  auto r = Rect::MakeXYWH(100, 100, 100, 100);
2211  auto p = Point(200, 200);
2212 
2213  test_outside(r, p);
2214  }
2215  {
2216  auto r = Rect::MakeXYWH(100, 100, 100, 100);
2217  auto p = Point(99, 99);
2218 
2219  test_outside(r, p);
2220  }
2221  {
2222  auto r = Rect::MakeXYWH(100, 100, 100, 100);
2223  auto p = Point(199, 199);
2224 
2225  test_inside(r, p);
2226  }
2227 
2228  {
2229  auto r = Rect::MakeMaximum();
2230  auto p = Point(199, 199);
2231 
2232  test_inside(r, p);
2233  }
2234 }

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

◆ TEST() [271/389]

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

Definition at line 2474 of file rect_unittests.cc.

2474  {
2475  auto check_nans = [](const Rect& a, const Rect& b, const std::string& label) {
2476  ASSERT_TRUE(a.IsFinite()) << label;
2477  ASSERT_TRUE(b.IsFinite()) << label;
2478  ASSERT_FALSE(a.IsEmpty());
2479 
2480  for (int i = 1; i < 16; i++) {
2481  // NaN in a produces false
2482  EXPECT_FALSE(swap_nan(a, i).Contains(b)) << label << ", index = " << i;
2483  // NaN in b produces false
2484  EXPECT_TRUE(a.Contains(swap_nan(b, i))) << label << ", index = " << i;
2485  // NaN in both is false
2486  for (int j = 1; j < 16; j++) {
2487  EXPECT_FALSE(swap_nan(a, i).Contains(swap_nan(b, j)))
2488  << label << ", indices = " << i << ", " << j;
2489  }
2490  }
2491  };
2492 
2493  auto check_empty_flips = [](const Rect& a, const Rect& b,
2494  const std::string& label) {
2495  ASSERT_FALSE(a.IsEmpty());
2496  // test b rects are allowed to have 0 w/h, but not be backwards
2497  ASSERT_FALSE(b.GetLeft() > b.GetRight() || b.GetTop() > b.GetBottom());
2498 
2499  // unflipped a vs flipped (empty) b yields false
2500  EXPECT_TRUE(a.Contains(flip_lr(b))) << label;
2501  EXPECT_TRUE(a.Contains(flip_tb(b))) << label;
2502  EXPECT_TRUE(a.Contains(flip_lrtb(b))) << label;
2503 
2504  // flipped (empty) a vs unflipped b yields false
2505  EXPECT_FALSE(flip_lr(a).Contains(b)) << label;
2506  EXPECT_FALSE(flip_tb(a).Contains(b)) << label;
2507  EXPECT_FALSE(flip_lrtb(a).Contains(b)) << label;
2508 
2509  // flipped (empty) a vs flipped (empty) b yields empty
2510  EXPECT_FALSE(flip_lr(a).Contains(flip_lr(b))) << label;
2511  EXPECT_FALSE(flip_tb(a).Contains(flip_tb(b))) << label;
2512  EXPECT_FALSE(flip_lrtb(a).Contains(flip_lrtb(b))) << label;
2513  };
2514 
2515  auto test_inside = [&check_nans, &check_empty_flips](const Rect& a,
2516  const Rect& b) {
2517  ASSERT_FALSE(a.IsEmpty()) << a;
2518  // test b rects are allowed to have 0 w/h, but not be backwards
2519  ASSERT_FALSE(b.GetLeft() > b.GetRight() || b.GetTop() > b.GetBottom());
2520 
2521  std::stringstream stream;
2522  stream << a << " contains " << b;
2523  auto label = stream.str();
2524 
2525  EXPECT_TRUE(a.Contains(b)) << label;
2526  check_empty_flips(a, b, label);
2527  check_nans(a, b, label);
2528  };
2529 
2530  auto test_not_inside = [&check_nans, &check_empty_flips](const Rect& a,
2531  const Rect& b) {
2532  ASSERT_FALSE(a.IsEmpty()) << a;
2533  // If b was empty, it would be contained and should not be tested with
2534  // this function - use |test_inside| instead.
2535  ASSERT_FALSE(b.IsEmpty()) << b;
2536 
2537  std::stringstream stream;
2538  stream << a << " contains " << b;
2539  auto label = stream.str();
2540 
2541  EXPECT_FALSE(a.Contains(b)) << label;
2542  check_empty_flips(a, b, label);
2543  check_nans(a, b, label);
2544  };
2545 
2546  {
2547  auto a = Rect::MakeXYWH(100, 100, 100, 100);
2548 
2549  test_inside(a, a);
2550  }
2551  {
2552  auto a = Rect::MakeXYWH(100, 100, 100, 100);
2553  auto b = Rect::MakeXYWH(0, 0, 0, 0);
2554 
2555  test_inside(a, b);
2556  }
2557  {
2558  auto a = Rect::MakeXYWH(100, 100, 100, 100);
2559  auto b = Rect::MakeXYWH(150, 150, 20, 20);
2560 
2561  test_inside(a, b);
2562  }
2563  {
2564  auto a = Rect::MakeXYWH(100, 100, 100, 100);
2565  auto b = Rect::MakeXYWH(150, 150, 100, 100);
2566 
2567  test_not_inside(a, b);
2568  }
2569  {
2570  auto a = Rect::MakeXYWH(100, 100, 100, 100);
2571  auto b = Rect::MakeXYWH(50, 50, 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(0, 0, 300, 300);
2578 
2579  test_not_inside(a, b);
2580  }
2581  {
2582  auto a = Rect::MakeMaximum();
2583  auto b = Rect::MakeXYWH(0, 0, 300, 300);
2584 
2585  test_inside(a, b);
2586  }
2587 }

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

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

Definition at line 654 of file rect_unittests.cc.

654  {
655  // Using fractional-power-of-2 friendly values for equality tests
656  Rect rect = Rect::MakeLTRB(5.125f, 10.25f, 20.625f, 25.375f);
657  Rect copy = rect;
658 
659  EXPECT_EQ(rect, copy);
660  EXPECT_EQ(copy.GetLeft(), 5.125f);
661  EXPECT_EQ(copy.GetTop(), 10.25f);
662  EXPECT_EQ(copy.GetRight(), 20.625f);
663  EXPECT_EQ(copy.GetBottom(), 25.375f);
664  EXPECT_EQ(copy.GetX(), 5.125f);
665  EXPECT_EQ(copy.GetY(), 10.25f);
666  EXPECT_EQ(copy.GetWidth(), 15.5f);
667  EXPECT_EQ(copy.GetHeight(), 15.125f);
668  EXPECT_FALSE(copy.IsEmpty());
669  EXPECT_TRUE(copy.IsFinite());
670 }

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

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

Definition at line 2682 of file rect_unittests.cc.

2682  {
2683  Rect cull_rect = Rect::MakeLTRB(20, 20, 40, 40);
2684 
2685  auto check_nans = [&cull_rect](const Rect& diff_rect,
2686  const std::string& label) {
2687  EXPECT_TRUE(cull_rect.IsFinite()) << label;
2688  EXPECT_TRUE(diff_rect.IsFinite()) << label;
2689 
2690  for (int i = 1; i < 16; i++) {
2691  // NaN in cull_rect produces empty
2692  EXPECT_FALSE(swap_nan(cull_rect, i).Cutout(diff_rect).has_value())
2693  << label << ", index " << i;
2694  EXPECT_EQ(swap_nan(cull_rect, i).CutoutOrEmpty(diff_rect), Rect())
2695  << label << ", index " << i;
2696 
2697  // NaN in diff_rect is nop
2698  EXPECT_TRUE(cull_rect.Cutout(swap_nan(diff_rect, i)).has_value())
2699  << label << ", index " << i;
2700  EXPECT_EQ(cull_rect.CutoutOrEmpty(swap_nan(diff_rect, i)), cull_rect)
2701  << label << ", index " << i;
2702 
2703  for (int j = 1; j < 16; j++) {
2704  // NaN in both is also empty
2705  EXPECT_FALSE(
2706  swap_nan(cull_rect, i).Cutout(swap_nan(diff_rect, j)).has_value())
2707  << label << ", indices " << i << ", " << j;
2708  EXPECT_EQ(swap_nan(cull_rect, i).CutoutOrEmpty(swap_nan(diff_rect, j)),
2709  Rect())
2710  << label << ", indices " << i << ", " << j;
2711  }
2712  }
2713  };
2714 
2715  auto check_empty_flips = [&cull_rect](const Rect& diff_rect,
2716  const std::string& label) {
2717  EXPECT_FALSE(cull_rect.IsEmpty()) << label;
2718  EXPECT_FALSE(diff_rect.IsEmpty()) << label;
2719 
2720  // unflipped cull_rect vs flipped(empty) diff_rect
2721  // == cull_rect
2722  EXPECT_TRUE(cull_rect.Cutout(flip_lr(diff_rect)).has_value()) << label;
2723  EXPECT_EQ(cull_rect.Cutout(flip_lr(diff_rect)), cull_rect) << label;
2724  EXPECT_TRUE(cull_rect.Cutout(flip_tb(diff_rect)).has_value()) << label;
2725  EXPECT_EQ(cull_rect.Cutout(flip_tb(diff_rect)), cull_rect) << label;
2726  EXPECT_TRUE(cull_rect.Cutout(flip_lrtb(diff_rect)).has_value()) << label;
2727  EXPECT_EQ(cull_rect.Cutout(flip_lrtb(diff_rect)), cull_rect) << label;
2728 
2729  // flipped(empty) cull_rect vs unflipped diff_rect
2730  // == empty
2731  EXPECT_FALSE(flip_lr(cull_rect).Cutout(diff_rect).has_value()) << label;
2732  EXPECT_EQ(flip_lr(cull_rect).CutoutOrEmpty(diff_rect), Rect()) << label;
2733  EXPECT_FALSE(flip_tb(cull_rect).Cutout(diff_rect).has_value()) << label;
2734  EXPECT_EQ(flip_tb(cull_rect).CutoutOrEmpty(diff_rect), Rect()) << label;
2735  EXPECT_FALSE(flip_lrtb(cull_rect).Cutout(diff_rect).has_value()) << label;
2736  EXPECT_EQ(flip_lrtb(cull_rect).CutoutOrEmpty(diff_rect), Rect()) << label;
2737 
2738  // flipped(empty) cull_rect vs flipped(empty) diff_rect
2739  // == empty
2740  EXPECT_FALSE(flip_lr(cull_rect).Cutout(flip_lr(diff_rect)).has_value())
2741  << label;
2742  EXPECT_EQ(flip_lr(cull_rect).CutoutOrEmpty(flip_lr(diff_rect)), Rect())
2743  << label;
2744  EXPECT_FALSE(flip_tb(cull_rect).Cutout(flip_tb(diff_rect)).has_value())
2745  << label;
2746  EXPECT_EQ(flip_tb(cull_rect).CutoutOrEmpty(flip_tb(diff_rect)), Rect())
2747  << label;
2748  EXPECT_FALSE(flip_lrtb(cull_rect).Cutout(flip_lrtb(diff_rect)).has_value())
2749  << label;
2750  EXPECT_EQ(flip_lrtb(cull_rect).CutoutOrEmpty(flip_lrtb(diff_rect)), Rect())
2751  << label;
2752  };
2753 
2754  auto non_reducing = [&cull_rect, &check_empty_flips, &check_nans](
2755  const Rect& diff_rect, const std::string& label) {
2756  EXPECT_EQ(cull_rect.Cutout(diff_rect), cull_rect) << label;
2757  EXPECT_EQ(cull_rect.CutoutOrEmpty(diff_rect), cull_rect) << label;
2758  check_empty_flips(diff_rect, label);
2759  check_nans(diff_rect, label);
2760  };
2761 
2762  auto reducing = [&cull_rect, &check_empty_flips, &check_nans](
2763  const Rect& diff_rect, const Rect& result_rect,
2764  const std::string& label) {
2765  EXPECT_TRUE(!result_rect.IsEmpty());
2766  EXPECT_EQ(cull_rect.Cutout(diff_rect), result_rect) << label;
2767  EXPECT_EQ(cull_rect.CutoutOrEmpty(diff_rect), result_rect) << label;
2768  check_empty_flips(diff_rect, label);
2769  check_nans(diff_rect, label);
2770  };
2771 
2772  auto emptying = [&cull_rect, &check_empty_flips, &check_nans](
2773  const Rect& diff_rect, const std::string& label) {
2774  EXPECT_FALSE(cull_rect.Cutout(diff_rect).has_value()) << label;
2775  EXPECT_EQ(cull_rect.CutoutOrEmpty(diff_rect), Rect()) << label;
2776  check_empty_flips(diff_rect, label);
2777  check_nans(diff_rect, label);
2778  };
2779 
2780  // Skim the corners and edge
2781  non_reducing(Rect::MakeLTRB(10, 10, 20, 20), "outside UL corner");
2782  non_reducing(Rect::MakeLTRB(20, 10, 40, 20), "Above");
2783  non_reducing(Rect::MakeLTRB(40, 10, 50, 20), "outside UR corner");
2784  non_reducing(Rect::MakeLTRB(40, 20, 50, 40), "Right");
2785  non_reducing(Rect::MakeLTRB(40, 40, 50, 50), "outside LR corner");
2786  non_reducing(Rect::MakeLTRB(20, 40, 40, 50), "Below");
2787  non_reducing(Rect::MakeLTRB(10, 40, 20, 50), "outside LR corner");
2788  non_reducing(Rect::MakeLTRB(10, 20, 20, 40), "Left");
2789 
2790  // Overlap corners
2791  non_reducing(Rect::MakeLTRB(15, 15, 25, 25), "covering UL corner");
2792  non_reducing(Rect::MakeLTRB(35, 15, 45, 25), "covering UR corner");
2793  non_reducing(Rect::MakeLTRB(35, 35, 45, 45), "covering LR corner");
2794  non_reducing(Rect::MakeLTRB(15, 35, 25, 45), "covering LL corner");
2795 
2796  // Overlap edges, but not across an entire side
2797  non_reducing(Rect::MakeLTRB(20, 15, 39, 25), "Top edge left-biased");
2798  non_reducing(Rect::MakeLTRB(21, 15, 40, 25), "Top edge, right biased");
2799  non_reducing(Rect::MakeLTRB(35, 20, 45, 39), "Right edge, top-biased");
2800  non_reducing(Rect::MakeLTRB(35, 21, 45, 40), "Right edge, bottom-biased");
2801  non_reducing(Rect::MakeLTRB(20, 35, 39, 45), "Bottom edge, left-biased");
2802  non_reducing(Rect::MakeLTRB(21, 35, 40, 45), "Bottom edge, right-biased");
2803  non_reducing(Rect::MakeLTRB(15, 20, 25, 39), "Left edge, top-biased");
2804  non_reducing(Rect::MakeLTRB(15, 21, 25, 40), "Left edge, bottom-biased");
2805 
2806  // Slice all the way through the middle
2807  non_reducing(Rect::MakeLTRB(25, 15, 35, 45), "Vertical interior slice");
2808  non_reducing(Rect::MakeLTRB(15, 25, 45, 35), "Horizontal interior slice");
2809 
2810  // Slice off each edge
2811  reducing(Rect::MakeLTRB(20, 15, 40, 25), //
2812  Rect::MakeLTRB(20, 25, 40, 40), //
2813  "Slice off top");
2814  reducing(Rect::MakeLTRB(35, 20, 45, 40), //
2815  Rect::MakeLTRB(20, 20, 35, 40), //
2816  "Slice off right");
2817  reducing(Rect::MakeLTRB(20, 35, 40, 45), //
2818  Rect::MakeLTRB(20, 20, 40, 35), //
2819  "Slice off bottom");
2820  reducing(Rect::MakeLTRB(15, 20, 25, 40), //
2821  Rect::MakeLTRB(25, 20, 40, 40), //
2822  "Slice off left");
2823 
2824  // cull rect contains diff rect
2825  non_reducing(Rect::MakeLTRB(21, 21, 39, 39), "Contained, non-covering");
2826 
2827  // cull rect equals diff rect
2828  emptying(cull_rect, "Perfectly covering");
2829 
2830  // diff rect contains cull rect
2831  emptying(Rect::MakeLTRB(15, 15, 45, 45), "Smothering");
2832 }

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

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

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

Definition at line 3024 of file rect_unittests.cc.

3024  {
3025  auto r = Rect::MakeLTRB(1, 2, 3, 4);
3026 
3027  EXPECT_EQ(r.GetLeft(), 1);
3028  EXPECT_EQ(r.GetTop(), 2);
3029  EXPECT_EQ(r.GetRight(), 3);
3030  EXPECT_EQ(r.GetBottom(), 4);
3031 
3032  EXPECT_POINT_NEAR(r.GetLeftTop(), Point(1, 2));
3033  EXPECT_POINT_NEAR(r.GetRightTop(), Point(3, 2));
3034  EXPECT_POINT_NEAR(r.GetLeftBottom(), Point(1, 4));
3035  EXPECT_POINT_NEAR(r.GetRightBottom(), Point(3, 4));
3036 }

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

◆ TEST() [276/389]

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

Definition at line 795 of file rect_unittests.cc.

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

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

◆ TEST() [277/389]

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

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

Definition at line 1236 of file rect_unittests.cc.

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

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

◆ TEST() [279/389]

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

Definition at line 640 of file rect_unittests.cc.

640  {
641  EXPECT_EQ(Rect(Rect::MakeXYWH(2, 3, 7, 15)),
642  Rect::MakeXYWH(2.0, 3.0, 7.0, 15.0));
643  EXPECT_EQ(Rect(Rect::MakeLTRB(2, 3, 7, 15)),
644  Rect::MakeLTRB(2.0, 3.0, 7.0, 15.0));
645 }

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

◆ TEST() [280/389]

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

Definition at line 1020 of file rect_unittests.cc.

1020  {
1021  {
1022  // Checks for expected matrix values
1023 
1024  auto r = Rect::MakeXYWH(100, 200, 200, 400);
1025 
1026  EXPECT_EQ(r.GetNormalizingTransform(),
1027  Matrix::MakeScale({0.005, 0.0025, 1.0}) *
1028  Matrix::MakeTranslation({-100, -200}));
1029  }
1030 
1031  {
1032  // Checks for expected transform of points relative to the rect
1033 
1034  auto r = Rect::MakeLTRB(300, 500, 400, 700);
1035  auto m = r.GetNormalizingTransform();
1036 
1037  // The 4 corners of the rect => (0, 0) to (1, 1)
1038  EXPECT_EQ(m * Point(300, 500), Point(0, 0));
1039  EXPECT_EQ(m * Point(400, 500), Point(1, 0));
1040  EXPECT_EQ(m * Point(400, 700), Point(1, 1));
1041  EXPECT_EQ(m * Point(300, 700), Point(0, 1));
1042 
1043  // The center => (0.5, 0.5)
1044  EXPECT_EQ(m * Point(350, 600), Point(0.5, 0.5));
1045 
1046  // Outside the 4 corners => (-1, -1) to (2, 2)
1047  EXPECT_EQ(m * Point(200, 300), Point(-1, -1));
1048  EXPECT_EQ(m * Point(500, 300), Point(2, -1));
1049  EXPECT_EQ(m * Point(500, 900), Point(2, 2));
1050  EXPECT_EQ(m * Point(200, 900), Point(-1, 2));
1051  }
1052 
1053  {
1054  // Checks for behavior with empty rects
1055 
1056  auto zero = Matrix::MakeScale({0.0, 0.0, 1.0});
1057 
1058  // Empty for width and/or height == 0
1059  EXPECT_EQ(Rect::MakeXYWH(10, 10, 0, 10).GetNormalizingTransform(), zero);
1060  EXPECT_EQ(Rect::MakeXYWH(10, 10, 10, 0).GetNormalizingTransform(), zero);
1061  EXPECT_EQ(Rect::MakeXYWH(10, 10, 0, 0).GetNormalizingTransform(), zero);
1062 
1063  // Empty for width and/or height < 0
1064  EXPECT_EQ(Rect::MakeXYWH(10, 10, -1, 10).GetNormalizingTransform(), zero);
1065  EXPECT_EQ(Rect::MakeXYWH(10, 10, 10, -1).GetNormalizingTransform(), zero);
1066  EXPECT_EQ(Rect::MakeXYWH(10, 10, -1, -1).GetNormalizingTransform(), zero);
1067  }
1068 
1069  {
1070  // Checks for behavior with non-finite rects
1071 
1072  auto z = Matrix::MakeScale({0.0, 0.0, 1.0});
1073  auto nan = std::numeric_limits<Scalar>::quiet_NaN();
1074  auto inf = std::numeric_limits<Scalar>::infinity();
1075 
1076  // Non-finite for width and/or height == nan
1077  EXPECT_EQ(Rect::MakeXYWH(10, 10, nan, 10).GetNormalizingTransform(), z);
1078  EXPECT_EQ(Rect::MakeXYWH(10, 10, 10, nan).GetNormalizingTransform(), z);
1079  EXPECT_EQ(Rect::MakeXYWH(10, 10, nan, nan).GetNormalizingTransform(), z);
1080 
1081  // Non-finite for width and/or height == inf
1082  EXPECT_EQ(Rect::MakeXYWH(10, 10, inf, 10).GetNormalizingTransform(), z);
1083  EXPECT_EQ(Rect::MakeXYWH(10, 10, 10, inf).GetNormalizingTransform(), z);
1084  EXPECT_EQ(Rect::MakeXYWH(10, 10, inf, inf).GetNormalizingTransform(), z);
1085 
1086  // Non-finite for width and/or height == -inf
1087  EXPECT_EQ(Rect::MakeXYWH(10, 10, -inf, 10).GetNormalizingTransform(), z);
1088  EXPECT_EQ(Rect::MakeXYWH(10, 10, 10, -inf).GetNormalizingTransform(), z);
1089  EXPECT_EQ(Rect::MakeXYWH(10, 10, -inf, -inf).GetNormalizingTransform(), z);
1090 
1091  // Non-finite for origin X and/or Y == nan
1092  EXPECT_EQ(Rect::MakeXYWH(nan, 10, 10, 10).GetNormalizingTransform(), z);
1093  EXPECT_EQ(Rect::MakeXYWH(10, nan, 10, 10).GetNormalizingTransform(), z);
1094  EXPECT_EQ(Rect::MakeXYWH(nan, nan, 10, 10).GetNormalizingTransform(), z);
1095 
1096  // Non-finite for origin X and/or Y == inf
1097  EXPECT_EQ(Rect::MakeXYWH(inf, 10, 10, 10).GetNormalizingTransform(), z);
1098  EXPECT_EQ(Rect::MakeXYWH(10, inf, 10, 10).GetNormalizingTransform(), z);
1099  EXPECT_EQ(Rect::MakeXYWH(inf, inf, 10, 10).GetNormalizingTransform(), z);
1100 
1101  // Non-finite for origin X and/or Y == -inf
1102  EXPECT_EQ(Rect::MakeXYWH(-inf, 10, 10, 10).GetNormalizingTransform(), z);
1103  EXPECT_EQ(Rect::MakeXYWH(10, -inf, 10, 10).GetNormalizingTransform(), z);
1104  EXPECT_EQ(Rect::MakeXYWH(-inf, -inf, 10, 10).GetNormalizingTransform(), z);
1105  }
1106 }

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

◆ TEST() [281/389]

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

Definition at line 2953 of file rect_unittests.cc.

2953  {
2954  {
2955  Rect r = Rect::MakeXYWH(100, 200, 300, 400);
2956  auto points = r.GetPoints();
2957  EXPECT_POINT_NEAR(points[0], Point(100, 200));
2958  EXPECT_POINT_NEAR(points[1], Point(400, 200));
2959  EXPECT_POINT_NEAR(points[2], Point(100, 600));
2960  EXPECT_POINT_NEAR(points[3], Point(400, 600));
2961  }
2962 
2963  {
2964  Rect r = Rect::MakeMaximum();
2965  auto points = r.GetPoints();
2966  EXPECT_EQ(points[0], Point(std::numeric_limits<float>::lowest(),
2967  std::numeric_limits<float>::lowest()));
2968  EXPECT_EQ(points[1], Point(std::numeric_limits<float>::max(),
2969  std::numeric_limits<float>::lowest()));
2970  EXPECT_EQ(points[2], Point(std::numeric_limits<float>::lowest(),
2971  std::numeric_limits<float>::max()));
2972  EXPECT_EQ(points[3], Point(std::numeric_limits<float>::max(),
2973  std::numeric_limits<float>::max()));
2974  }
2975 }

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

◆ TEST() [282/389]

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

Definition at line 3010 of file rect_unittests.cc.

3010  {
3011  {
3012  Rect r = Rect::MakeXYWH(100, 200, 300, 400);
3013  auto actual = r.GetPositive();
3014  EXPECT_RECT_NEAR(r, actual);
3015  }
3016  {
3017  Rect r = Rect::MakeXYWH(100, 200, -100, -100);
3018  auto actual = r.GetPositive();
3019  Rect expected = Rect::MakeXYWH(0, 100, 100, 100);
3020  EXPECT_RECT_NEAR(expected, actual);
3021  }
3022 }

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

◆ TEST() [283/389]

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

Definition at line 2984 of file rect_unittests.cc.

2984  {
2985  Rect r = Rect::MakeXYWH(100, 200, 300, 400);
2986  auto points = r.GetTransformedPoints(Matrix::MakeTranslation({10, 20}));
2987  EXPECT_POINT_NEAR(points[0], Point(110, 220));
2988  EXPECT_POINT_NEAR(points[1], Point(410, 220));
2989  EXPECT_POINT_NEAR(points[2], Point(110, 620));
2990  EXPECT_POINT_NEAR(points[3], Point(410, 620));
2991 }

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

◆ TEST() [284/389]

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

Definition at line 1611 of file rect_unittests.cc.

1611  {
1612  auto check_nans = [](const Rect& a, const Rect& b, const std::string& label) {
1613  ASSERT_TRUE(a.IsFinite()) << label;
1614  ASSERT_TRUE(b.IsFinite()) << label;
1615 
1616  for (int i = 1; i < 16; i++) {
1617  // NaN in a produces empty
1618  EXPECT_FALSE(swap_nan(a, i).Intersection(b).has_value())
1619  << label << ", index = " << i;
1620  // NaN in b produces empty
1621  EXPECT_FALSE(a.Intersection(swap_nan(b, i)).has_value())
1622  << label << ", index = " << i;
1623  // NaN in both is empty
1624  for (int j = 1; j < 16; j++) {
1625  EXPECT_FALSE(swap_nan(a, i).Intersection(swap_nan(b, j)).has_value())
1626  << label << ", indices = " << i << ", " << j;
1627  }
1628  }
1629  };
1630 
1631  auto check_empty_flips = [](const Rect& a, const Rect& b,
1632  const std::string& label) {
1633  ASSERT_FALSE(a.IsEmpty());
1634  // b is allowed to be empty
1635 
1636  // unflipped a vs flipped (empty) b yields a
1637  EXPECT_FALSE(a.Intersection(flip_lr(b)).has_value()) << label;
1638  EXPECT_TRUE(a.IntersectionOrEmpty(flip_lr(b)).IsEmpty()) << label;
1639  EXPECT_FALSE(a.Intersection(flip_tb(b)).has_value()) << label;
1640  EXPECT_TRUE(a.IntersectionOrEmpty(flip_tb(b)).IsEmpty()) << label;
1641  EXPECT_FALSE(a.Intersection(flip_lrtb(b)).has_value()) << label;
1642  EXPECT_TRUE(a.IntersectionOrEmpty(flip_lrtb(b)).IsEmpty()) << label;
1643 
1644  // flipped (empty) a vs unflipped b yields b
1645  EXPECT_FALSE(flip_lr(a).Intersection(b).has_value()) << label;
1646  EXPECT_TRUE(flip_lr(a).IntersectionOrEmpty(b).IsEmpty()) << label;
1647  EXPECT_FALSE(flip_tb(a).Intersection(b).has_value()) << label;
1648  EXPECT_TRUE(flip_tb(a).IntersectionOrEmpty(b).IsEmpty()) << label;
1649  EXPECT_FALSE(flip_lrtb(a).Intersection(b).has_value()) << label;
1650  EXPECT_TRUE(flip_lrtb(a).IntersectionOrEmpty(b).IsEmpty()) << label;
1651 
1652  // flipped (empty) a vs flipped (empty) b yields empty
1653  EXPECT_FALSE(flip_lr(a).Intersection(flip_lr(b)).has_value()) << label;
1654  EXPECT_TRUE(flip_lr(a).IntersectionOrEmpty(flip_lr(b)).IsEmpty()) << label;
1655  EXPECT_FALSE(flip_tb(a).Intersection(flip_tb(b)).has_value()) << label;
1656  EXPECT_TRUE(flip_tb(a).IntersectionOrEmpty(flip_tb(b)).IsEmpty()) << label;
1657  EXPECT_FALSE(flip_lrtb(a).Intersection(flip_lrtb(b)).has_value()) << label;
1658  EXPECT_TRUE(flip_lrtb(a).IntersectionOrEmpty(flip_lrtb(b)).IsEmpty())
1659  << label;
1660  };
1661 
1662  auto test_non_empty = [&check_nans, &check_empty_flips](
1663  const Rect& a, const Rect& b, const Rect& result) {
1664  ASSERT_FALSE(a.IsEmpty()) << a;
1665  // b is allowed to be empty
1666 
1667  std::stringstream stream;
1668  stream << a << " union " << b;
1669  auto label = stream.str();
1670 
1671  EXPECT_TRUE(a.Intersection(b).has_value()) << label;
1672  EXPECT_TRUE(b.Intersection(a).has_value()) << label;
1673  EXPECT_EQ(a.Intersection(b), result) << label;
1674  EXPECT_EQ(b.Intersection(a), result) << label;
1675  check_empty_flips(a, b, label);
1676  check_nans(a, b, label);
1677  };
1678 
1679  auto test_empty = [&check_nans, &check_empty_flips](const Rect& a,
1680  const Rect& b) {
1681  ASSERT_FALSE(a.IsEmpty()) << a;
1682  // b is allowed to be empty
1683 
1684  std::stringstream stream;
1685  stream << a << " union " << b;
1686  auto label = stream.str();
1687 
1688  EXPECT_FALSE(a.Intersection(b).has_value()) << label;
1689  EXPECT_TRUE(a.IntersectionOrEmpty(b).IsEmpty()) << label;
1690  EXPECT_FALSE(b.Intersection(a).has_value()) << label;
1691  EXPECT_TRUE(b.IntersectionOrEmpty(a).IsEmpty()) << label;
1692  check_empty_flips(a, b, label);
1693  check_nans(a, b, label);
1694  };
1695 
1696  {
1697  auto a = Rect::MakeXYWH(100, 100, 100, 100);
1698  auto b = Rect::MakeXYWH(0, 0, 0, 0);
1699 
1700  test_empty(a, b);
1701  }
1702 
1703  {
1704  auto a = Rect::MakeXYWH(100, 100, 100, 100);
1705  auto b = Rect::MakeXYWH(10, 10, 0, 0);
1706 
1707  test_empty(a, b);
1708  }
1709 
1710  {
1711  auto a = Rect::MakeXYWH(0, 0, 100, 100);
1712  auto b = Rect::MakeXYWH(10, 10, 100, 100);
1713  auto expected = Rect::MakeXYWH(10, 10, 90, 90);
1714 
1715  test_non_empty(a, b, expected);
1716  }
1717 
1718  {
1719  auto a = Rect::MakeXYWH(0, 0, 100, 100);
1720  auto b = Rect::MakeXYWH(100, 100, 100, 100);
1721 
1722  test_empty(a, b);
1723  }
1724 
1725  {
1726  auto a = Rect::MakeMaximum();
1727  auto b = Rect::MakeXYWH(10, 10, 300, 300);
1728 
1729  test_non_empty(a, b, b);
1730  }
1731 
1732  {
1733  auto a = Rect::MakeMaximum();
1734  auto b = Rect::MakeMaximum();
1735 
1736  test_non_empty(a, b, Rect::MakeMaximum());
1737  }
1738 }

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

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

Definition at line 1945 of file rect_unittests.cc.

1945  {
1946  auto check_nans = [](const Rect& a, const Rect& b, const std::string& label) {
1947  ASSERT_TRUE(a.IsFinite()) << label;
1948  ASSERT_TRUE(b.IsFinite()) << label;
1949 
1950  for (int i = 1; i < 16; i++) {
1951  // NaN in a produces b
1952  EXPECT_FALSE(swap_nan(a, i).IntersectsWithRect(b))
1953  << label << ", index = " << i;
1954  // NaN in b produces a
1955  EXPECT_FALSE(a.IntersectsWithRect(swap_nan(b, i)))
1956  << label << ", index = " << i;
1957  // NaN in both is empty
1958  for (int j = 1; j < 16; j++) {
1959  EXPECT_FALSE(swap_nan(a, i).IntersectsWithRect(swap_nan(b, j)))
1960  << label << ", indices = " << i << ", " << j;
1961  }
1962  }
1963  };
1964 
1965  auto check_empty_flips = [](const Rect& a, const Rect& b,
1966  const std::string& label) {
1967  ASSERT_FALSE(a.IsEmpty());
1968  // b is allowed to be empty
1969 
1970  // unflipped a vs flipped (empty) b yields a
1971  EXPECT_FALSE(a.IntersectsWithRect(flip_lr(b))) << label;
1972  EXPECT_FALSE(a.IntersectsWithRect(flip_tb(b))) << label;
1973  EXPECT_FALSE(a.IntersectsWithRect(flip_lrtb(b))) << label;
1974 
1975  // flipped (empty) a vs unflipped b yields b
1976  EXPECT_FALSE(flip_lr(a).IntersectsWithRect(b)) << label;
1977  EXPECT_FALSE(flip_tb(a).IntersectsWithRect(b)) << label;
1978  EXPECT_FALSE(flip_lrtb(a).IntersectsWithRect(b)) << label;
1979 
1980  // flipped (empty) a vs flipped (empty) b yields empty
1981  EXPECT_FALSE(flip_lr(a).IntersectsWithRect(flip_lr(b))) << label;
1982  EXPECT_FALSE(flip_tb(a).IntersectsWithRect(flip_tb(b))) << label;
1983  EXPECT_FALSE(flip_lrtb(a).IntersectsWithRect(flip_lrtb(b))) << label;
1984  };
1985 
1986  auto test_non_empty = [&check_nans, &check_empty_flips](const Rect& a,
1987  const Rect& b) {
1988  ASSERT_FALSE(a.IsEmpty()) << a;
1989  // b is allowed to be empty
1990 
1991  std::stringstream stream;
1992  stream << a << " union " << b;
1993  auto label = stream.str();
1994 
1995  EXPECT_TRUE(a.IntersectsWithRect(b)) << label;
1996  EXPECT_TRUE(b.IntersectsWithRect(a)) << label;
1997  check_empty_flips(a, b, label);
1998  check_nans(a, b, label);
1999  };
2000 
2001  auto test_empty = [&check_nans, &check_empty_flips](const Rect& a,
2002  const Rect& b) {
2003  ASSERT_FALSE(a.IsEmpty()) << a;
2004  // b is allowed to be empty
2005 
2006  std::stringstream stream;
2007  stream << a << " union " << b;
2008  auto label = stream.str();
2009 
2010  EXPECT_FALSE(a.IntersectsWithRect(b)) << label;
2011  EXPECT_FALSE(b.IntersectsWithRect(a)) << label;
2012  check_empty_flips(a, b, label);
2013  check_nans(a, b, label);
2014  };
2015 
2016  {
2017  auto a = Rect::MakeXYWH(100, 100, 100, 100);
2018  auto b = Rect::MakeXYWH(0, 0, 0, 0);
2019 
2020  test_empty(a, b);
2021  }
2022 
2023  {
2024  auto a = Rect::MakeXYWH(100, 100, 100, 100);
2025  auto b = Rect::MakeXYWH(10, 10, 0, 0);
2026 
2027  test_empty(a, b);
2028  }
2029 
2030  {
2031  auto a = Rect::MakeXYWH(0, 0, 100, 100);
2032  auto b = Rect::MakeXYWH(10, 10, 100, 100);
2033 
2034  test_non_empty(a, b);
2035  }
2036 
2037  {
2038  auto a = Rect::MakeXYWH(0, 0, 100, 100);
2039  auto b = Rect::MakeXYWH(100, 100, 100, 100);
2040 
2041  test_empty(a, b);
2042  }
2043 
2044  {
2045  auto a = Rect::MakeMaximum();
2046  auto b = Rect::MakeXYWH(10, 10, 100, 100);
2047 
2048  test_non_empty(a, b);
2049  }
2050 
2051  {
2052  auto a = Rect::MakeMaximum();
2053  auto b = Rect::MakeMaximum();
2054 
2055  test_non_empty(a, b);
2056  }
2057 }

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

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

Definition at line 606 of file rect_unittests.cc.

606  {
607  Rect rect = Rect::MakeMaximum();
608  auto inf = std::numeric_limits<Scalar>::infinity();
609  auto min = std::numeric_limits<Scalar>::lowest();
610  auto max = std::numeric_limits<Scalar>::max();
611 
612  EXPECT_EQ(rect.GetLeft(), min);
613  EXPECT_EQ(rect.GetTop(), min);
614  EXPECT_EQ(rect.GetRight(), max);
615  EXPECT_EQ(rect.GetBottom(), max);
616  EXPECT_EQ(rect.GetX(), min);
617  EXPECT_EQ(rect.GetY(), min);
618  EXPECT_EQ(rect.GetWidth(), inf);
619  EXPECT_EQ(rect.GetHeight(), inf);
620  EXPECT_FALSE(rect.IsEmpty());
621  EXPECT_TRUE(rect.IsFinite());
622 }

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

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

Definition at line 2993 of file rect_unittests.cc.

2993  {
2994  {
2995  std::vector<Point> points{{1, 5}, {4, -1}, {0, 6}};
2996  auto r = Rect::MakePointBounds(points.begin(), points.end());
2997  auto expected = Rect::MakeXYWH(0, -1, 4, 7);
2998  EXPECT_TRUE(r.has_value());
2999  if (r.has_value()) {
3000  EXPECT_RECT_NEAR(r.value(), expected);
3001  }
3002  }
3003  {
3004  std::vector<Point> points;
3005  std::optional<Rect> r = Rect::MakePointBounds(points.begin(), points.end());
3006  EXPECT_FALSE(r.has_value());
3007  }
3008 }

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

◆ TEST() [288/389]

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

Definition at line 576 of file rect_unittests.cc.

576  {
577  {
578  Size s(100, 200);
579  Rect r = Rect::MakeSize(s);
580  Rect expected = Rect::MakeLTRB(0, 0, 100, 200);
581  EXPECT_RECT_NEAR(r, expected);
582  }
583 
584  {
585  ISize s(100, 200);
586  Rect r = Rect::MakeSize(s);
587  Rect expected = Rect::MakeLTRB(0, 0, 100, 200);
588  EXPECT_RECT_NEAR(r, expected);
589  }
590 
591  {
592  Size s(100, 200);
593  IRect r = IRect::MakeSize(s);
594  IRect expected = IRect::MakeLTRB(0, 0, 100, 200);
595  EXPECT_EQ(r, expected);
596  }
597 
598  {
599  ISize s(100, 200);
600  IRect r = IRect::MakeSize(s);
601  IRect expected = IRect::MakeLTRB(0, 0, 100, 200);
602  EXPECT_EQ(r, expected);
603  }
604 }

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

◆ TEST() [289/389]

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

Definition at line 688 of file rect_unittests.cc.

688  {
689  {
690  Rect r = Rect::MakeOriginSize({10, 20}, {50, 40});
691  EXPECT_EQ(r.GetOrigin(), Point(10, 20));
692  EXPECT_EQ(r.GetSize(), Size(50, 40));
693  EXPECT_EQ(r.GetX(), 10);
694  EXPECT_EQ(r.GetY(), 20);
695  EXPECT_EQ(r.GetWidth(), 50);
696  EXPECT_EQ(r.GetHeight(), 40);
697  auto expected_array = std::array<Scalar, 4>{10, 20, 50, 40};
698  EXPECT_EQ(r.GetXYWH(), expected_array);
699  }
700 
701  {
702  Rect r = Rect::MakeLTRB(10, 20, 50, 40);
703  EXPECT_EQ(r.GetOrigin(), Point(10, 20));
704  EXPECT_EQ(r.GetSize(), Size(40, 20));
705  EXPECT_EQ(r.GetX(), 10);
706  EXPECT_EQ(r.GetY(), 20);
707  EXPECT_EQ(r.GetWidth(), 40);
708  EXPECT_EQ(r.GetHeight(), 20);
709  auto expected_array = std::array<Scalar, 4>{10, 20, 40, 20};
710  EXPECT_EQ(r.GetXYWH(), expected_array);
711  }
712 }

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

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

Definition at line 370 of file rect_unittests.cc.

370  {
371  auto min = std::numeric_limits<Scalar>::lowest();
372  auto max = std::numeric_limits<Scalar>::max();
373  auto inf = std::numeric_limits<Scalar>::infinity();
374 
375  // 8 cases:
376  // finite negative X, max W
377  // ~min X, ~max W
378  // finite negative Y, max H
379  // ~min Y, ~max H
380  // finite positive X, min W
381  // ~min X, ~min W
382  // finite positive Y, min H
383  // ~min Y, ~min H
384 
385  // a small finite value subtracted from a max value will remain max
386  // a very large finite value (like min) subtracted from max will go to inf
387 
388  {
389  Rect rect = Rect::MakeLTRB(-5.0f, 10.0f, max, 25.0f);
390 
391  EXPECT_EQ(rect.GetLeft(), -5.0f);
392  EXPECT_EQ(rect.GetTop(), 10.0f);
393  EXPECT_EQ(rect.GetRight(), max);
394  EXPECT_EQ(rect.GetBottom(), 25.0f);
395  EXPECT_EQ(rect.GetX(), -5.0f);
396  EXPECT_EQ(rect.GetY(), 10.0f);
397  EXPECT_EQ(rect.GetWidth(), max);
398  EXPECT_EQ(rect.GetHeight(), 15.0f);
399  EXPECT_FALSE(rect.IsEmpty());
400  EXPECT_TRUE(rect.IsFinite());
401  }
402 
403  {
404  Rect rect = Rect::MakeLTRB(min + 5.0f, 10.0f, max - 5.0f, 25.0f);
405 
406  EXPECT_EQ(rect.GetLeft(), min + 5.0f);
407  EXPECT_EQ(rect.GetTop(), 10.0f);
408  EXPECT_EQ(rect.GetRight(), max - 5.0f);
409  EXPECT_EQ(rect.GetBottom(), 25.0f);
410  EXPECT_EQ(rect.GetX(), min + 5.0f);
411  EXPECT_EQ(rect.GetY(), 10.0f);
412  EXPECT_EQ(rect.GetWidth(), inf);
413  EXPECT_EQ(rect.GetHeight(), 15.0f);
414  EXPECT_FALSE(rect.IsEmpty());
415  EXPECT_TRUE(rect.IsFinite());
416  }
417 
418  {
419  Rect rect = Rect::MakeLTRB(5.0f, -10.0f, 20.0f, max);
420 
421  EXPECT_EQ(rect.GetLeft(), 5.0f);
422  EXPECT_EQ(rect.GetTop(), -10.0f);
423  EXPECT_EQ(rect.GetRight(), 20.0f);
424  EXPECT_EQ(rect.GetBottom(), max);
425  EXPECT_EQ(rect.GetX(), 5.0f);
426  EXPECT_EQ(rect.GetY(), -10.0f);
427  EXPECT_EQ(rect.GetWidth(), 15.0f);
428  EXPECT_EQ(rect.GetHeight(), max);
429  EXPECT_FALSE(rect.IsEmpty());
430  EXPECT_TRUE(rect.IsFinite());
431  }
432 
433  {
434  Rect rect = Rect::MakeLTRB(5.0f, min + 10.0f, 20.0f, max - 15.0f);
435 
436  EXPECT_EQ(rect.GetLeft(), 5.0f);
437  EXPECT_EQ(rect.GetTop(), min + 10.0f);
438  EXPECT_EQ(rect.GetRight(), 20.0f);
439  EXPECT_EQ(rect.GetBottom(), max - 15.0f);
440  EXPECT_EQ(rect.GetX(), 5.0f);
441  EXPECT_EQ(rect.GetY(), min + 10.0f);
442  EXPECT_EQ(rect.GetWidth(), 15.0f);
443  EXPECT_EQ(rect.GetHeight(), inf);
444  EXPECT_FALSE(rect.IsEmpty());
445  EXPECT_TRUE(rect.IsFinite());
446  }
447 
448  {
449  Rect rect = Rect::MakeLTRB(5.0f, 10.0f, min, 25.0f);
450 
451  EXPECT_EQ(rect.GetLeft(), 5.0f);
452  EXPECT_EQ(rect.GetTop(), 10.0f);
453  EXPECT_EQ(rect.GetRight(), min);
454  EXPECT_EQ(rect.GetBottom(), 25.0f);
455  EXPECT_EQ(rect.GetX(), 5.0f);
456  EXPECT_EQ(rect.GetY(), 10.0f);
457  EXPECT_EQ(rect.GetWidth(), min);
458  EXPECT_EQ(rect.GetHeight(), 15.0f);
459  EXPECT_TRUE(rect.IsEmpty());
460  EXPECT_TRUE(rect.IsFinite());
461  }
462 
463  {
464  Rect rect = Rect::MakeLTRB(max - 5.0f, 10.0f, min + 10.0f, 25.0f);
465 
466  EXPECT_EQ(rect.GetLeft(), max - 5.0f);
467  EXPECT_EQ(rect.GetTop(), 10.0f);
468  EXPECT_EQ(rect.GetRight(), min + 10.0f);
469  EXPECT_EQ(rect.GetBottom(), 25.0f);
470  EXPECT_EQ(rect.GetX(), max - 5.0f);
471  EXPECT_EQ(rect.GetY(), 10.0f);
472  EXPECT_EQ(rect.GetWidth(), -inf);
473  EXPECT_EQ(rect.GetHeight(), 15.0f);
474  EXPECT_TRUE(rect.IsEmpty());
475  EXPECT_TRUE(rect.IsFinite());
476  }
477 
478  {
479  Rect rect = Rect::MakeLTRB(5.0f, 10.0f, 20.0f, min);
480 
481  EXPECT_EQ(rect.GetLeft(), 5.0f);
482  EXPECT_EQ(rect.GetTop(), 10.0f);
483  EXPECT_EQ(rect.GetRight(), 20.0f);
484  EXPECT_EQ(rect.GetBottom(), min);
485  EXPECT_EQ(rect.GetX(), 5.0f);
486  EXPECT_EQ(rect.GetY(), 10.0f);
487  EXPECT_EQ(rect.GetWidth(), 15.0f);
488  EXPECT_EQ(rect.GetHeight(), min);
489  EXPECT_TRUE(rect.IsEmpty());
490  EXPECT_TRUE(rect.IsFinite());
491  }
492 
493  {
494  Rect rect = Rect::MakeLTRB(5.0f, max - 5.0f, 20.0f, min + 10.0f);
495 
496  EXPECT_EQ(rect.GetLeft(), 5.0f);
497  EXPECT_EQ(rect.GetTop(), max - 5.0f);
498  EXPECT_EQ(rect.GetRight(), 20.0f);
499  EXPECT_EQ(rect.GetBottom(), min + 10.0f);
500  EXPECT_EQ(rect.GetX(), 5.0f);
501  EXPECT_EQ(rect.GetY(), max - 5.0f);
502  EXPECT_EQ(rect.GetWidth(), 15.0f);
503  EXPECT_EQ(rect.GetHeight(), -inf);
504  EXPECT_TRUE(rect.IsEmpty());
505  EXPECT_TRUE(rect.IsFinite());
506  }
507 }

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

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

Definition at line 164 of file rect_unittests.cc.

164  {
165  auto min = std::numeric_limits<Scalar>::lowest();
166  auto max = std::numeric_limits<Scalar>::max();
167  auto inf = std::numeric_limits<Scalar>::infinity();
168 
169  // 8 cases:
170  // finite X, max W
171  // max X, max W
172  // finite Y, max H
173  // max Y, max H
174  // finite X, min W
175  // min X, min W
176  // finite Y, min H
177  // min Y, min H
178 
179  // a small finite value added to a max value will remain max
180  // a very large finite value (like max) added to max will go to infinity
181 
182  {
183  Rect rect = Rect::MakeXYWH(5.0, 10.0f, max, 15.0f);
184 
185  EXPECT_EQ(rect.GetLeft(), 5.0f);
186  EXPECT_EQ(rect.GetTop(), 10.0f);
187  EXPECT_EQ(rect.GetRight(), max);
188  EXPECT_EQ(rect.GetBottom(), 25.0f);
189  EXPECT_EQ(rect.GetX(), 5.0f);
190  EXPECT_EQ(rect.GetY(), 10.0f);
191  EXPECT_EQ(rect.GetWidth(), max);
192  EXPECT_EQ(rect.GetHeight(), 15.0f);
193  EXPECT_FALSE(rect.IsEmpty());
194  EXPECT_TRUE(rect.IsFinite());
195  }
196 
197  {
198  Rect rect = Rect::MakeXYWH(max, 10.0f, max, 15.0f);
199 
200  EXPECT_EQ(rect.GetLeft(), max);
201  EXPECT_EQ(rect.GetTop(), 10.0f);
202  EXPECT_EQ(rect.GetRight(), inf);
203  EXPECT_EQ(rect.GetBottom(), 25.0f);
204  EXPECT_EQ(rect.GetX(), max);
205  EXPECT_EQ(rect.GetY(), 10.0f);
206  EXPECT_EQ(rect.GetWidth(), inf);
207  EXPECT_EQ(rect.GetHeight(), 15.0f);
208  EXPECT_FALSE(rect.IsEmpty());
209  EXPECT_FALSE(rect.IsFinite());
210  }
211 
212  {
213  Rect rect = Rect::MakeXYWH(5.0f, 10.0f, 20.0f, max);
214 
215  EXPECT_EQ(rect.GetLeft(), 5.0f);
216  EXPECT_EQ(rect.GetTop(), 10.0f);
217  EXPECT_EQ(rect.GetRight(), 25.0f);
218  EXPECT_EQ(rect.GetBottom(), max);
219  EXPECT_EQ(rect.GetX(), 5.0f);
220  EXPECT_EQ(rect.GetY(), 10.0f);
221  EXPECT_EQ(rect.GetWidth(), 20.0f);
222  EXPECT_EQ(rect.GetHeight(), max);
223  EXPECT_FALSE(rect.IsEmpty());
224  EXPECT_TRUE(rect.IsFinite());
225  }
226 
227  {
228  Rect rect = Rect::MakeXYWH(5.0f, max, 20.0f, max);
229 
230  EXPECT_EQ(rect.GetLeft(), 5.0f);
231  EXPECT_EQ(rect.GetTop(), max);
232  EXPECT_EQ(rect.GetRight(), 25.0f);
233  EXPECT_EQ(rect.GetBottom(), inf);
234  EXPECT_EQ(rect.GetX(), 5.0f);
235  EXPECT_EQ(rect.GetY(), max);
236  EXPECT_EQ(rect.GetWidth(), 20.0f);
237  EXPECT_EQ(rect.GetHeight(), inf);
238  EXPECT_FALSE(rect.IsEmpty());
239  EXPECT_FALSE(rect.IsFinite());
240  }
241 
242  {
243  Rect rect = Rect::MakeXYWH(5.0, 10.0f, min, 15.0f);
244 
245  EXPECT_EQ(rect.GetLeft(), 5.0f);
246  EXPECT_EQ(rect.GetTop(), 10.0f);
247  EXPECT_EQ(rect.GetRight(), min);
248  EXPECT_EQ(rect.GetBottom(), 25.0f);
249  EXPECT_EQ(rect.GetX(), 5.0f);
250  EXPECT_EQ(rect.GetY(), 10.0f);
251  EXPECT_EQ(rect.GetWidth(), min);
252  EXPECT_EQ(rect.GetHeight(), 15.0f);
253  EXPECT_TRUE(rect.IsEmpty());
254  EXPECT_TRUE(rect.IsFinite());
255  }
256 
257  {
258  Rect rect = Rect::MakeXYWH(min, 10.0f, min, 15.0f);
259 
260  EXPECT_EQ(rect.GetLeft(), min);
261  EXPECT_EQ(rect.GetTop(), 10.0f);
262  EXPECT_EQ(rect.GetRight(), -inf);
263  EXPECT_EQ(rect.GetBottom(), 25.0f);
264  EXPECT_EQ(rect.GetX(), min);
265  EXPECT_EQ(rect.GetY(), 10.0f);
266  EXPECT_EQ(rect.GetWidth(), -inf);
267  EXPECT_EQ(rect.GetHeight(), 15.0f);
268  EXPECT_TRUE(rect.IsEmpty());
269  EXPECT_FALSE(rect.IsFinite());
270  }
271 
272  {
273  Rect rect = Rect::MakeXYWH(5.0f, 10.0f, 20.0f, min);
274 
275  EXPECT_EQ(rect.GetLeft(), 5.0f);
276  EXPECT_EQ(rect.GetTop(), 10.0f);
277  EXPECT_EQ(rect.GetRight(), 25.0f);
278  EXPECT_EQ(rect.GetBottom(), min);
279  EXPECT_EQ(rect.GetX(), 5.0f);
280  EXPECT_EQ(rect.GetY(), 10.0f);
281  EXPECT_EQ(rect.GetWidth(), 20.0f);
282  EXPECT_EQ(rect.GetHeight(), min);
283  EXPECT_TRUE(rect.IsEmpty());
284  EXPECT_TRUE(rect.IsFinite());
285  }
286 
287  {
288  Rect rect = Rect::MakeXYWH(5.0f, min, 20.0f, min);
289 
290  EXPECT_EQ(rect.GetLeft(), 5.0f);
291  EXPECT_EQ(rect.GetTop(), min);
292  EXPECT_EQ(rect.GetRight(), 25.0f);
293  EXPECT_EQ(rect.GetBottom(), -inf);
294  EXPECT_EQ(rect.GetX(), 5.0f);
295  EXPECT_EQ(rect.GetY(), min);
296  EXPECT_EQ(rect.GetWidth(), 20.0f);
297  EXPECT_EQ(rect.GetHeight(), -inf);
298  EXPECT_TRUE(rect.IsEmpty());
299  EXPECT_FALSE(rect.IsFinite());
300  }
301 }

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

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

Definition at line 3038 of file rect_unittests.cc.

3038  {
3039  {
3040  auto r = Rect::MakeLTRB(-100, -100, 100, 100);
3041  auto actual = r.Project(r);
3042  auto expected = Rect::MakeLTRB(0, 0, 1, 1);
3043  EXPECT_RECT_NEAR(expected, actual);
3044  }
3045  {
3046  auto r = Rect::MakeLTRB(-100, -100, 100, 100);
3047  auto actual = r.Project(Rect::MakeLTRB(0, 0, 100, 100));
3048  auto expected = Rect::MakeLTRB(0.5, 0.5, 1, 1);
3049  EXPECT_RECT_NEAR(expected, actual);
3050  }
3051 }

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

◆ TEST() [293/389]

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

Definition at line 3077 of file rect_unittests.cc.

3077  {
3078  {
3079  auto r = Rect::MakeLTRB(-100, -200, 300, 400);
3080  EXPECT_EQ(Rect::Round(r), r);
3081  }
3082  {
3083  auto r = Rect::MakeLTRB(-100.4, -200.4, 300.4, 400.4);
3084  EXPECT_EQ(Rect::Round(r), Rect::MakeLTRB(-100, -200, 300, 400));
3085  }
3086  {
3087  auto r = Rect::MakeLTRB(-100.5, -200.5, 300.5, 400.5);
3088  EXPECT_EQ(Rect::Round(r), Rect::MakeLTRB(-101, -201, 301, 401));
3089  }
3090 }

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

◆ TEST() [294/389]

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

Definition at line 3053 of file rect_unittests.cc.

3053  {
3054  {
3055  auto r = Rect::MakeLTRB(-100, -200, 300, 400);
3056  EXPECT_EQ(Rect::RoundOut(r), r);
3057  }
3058  {
3059  auto r = Rect::MakeLTRB(-100.1, -200.1, 300.1, 400.1);
3060  EXPECT_EQ(Rect::RoundOut(r), Rect::MakeLTRB(-101, -201, 301, 401));
3061  }
3062 }

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

◆ TEST() [295/389]

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

Definition at line 740 of file rect_unittests.cc.

740  {
741  Rect rect;
742 
743  EXPECT_EQ(Rect::RoundOut(rect), Rect());
744 
745  EXPECT_EQ(IRect::RoundOut(rect), IRect());
746 }

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

◆ TEST() [296/389]

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

Definition at line 748 of file rect_unittests.cc.

748  {
749  Rect rect = Rect::MakeLTRB(5.125f, 10.75f, 20.625f, 25.375f);
750 
751  EXPECT_EQ(Rect::RoundOut(rect), Rect::MakeLTRB(5.0f, 10.0f, 21.0f, 26.0f));
752 
753  EXPECT_EQ(IRect::RoundOut(rect), IRect::MakeLTRB(5, 10, 21, 26));
754 }

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

◆ TEST() [297/389]

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

Definition at line 756 of file rect_unittests.cc.

756  {
757  auto test = [](int corners) {
758  EXPECT_TRUE(corners >= 0 && corners <= 0xf);
759  Scalar l, t, r, b;
760  int64_t il, it, ir, ib;
761  l = il = 50;
762  t = it = 50;
763  r = ir = 80;
764  b = ib = 80;
765  if ((corners & (1 << 0)) != 0) {
766  l = -1E20;
767  il = std::numeric_limits<int64_t>::min();
768  }
769  if ((corners & (1 << 1)) != 0) {
770  t = -1E20;
771  it = std::numeric_limits<int64_t>::min();
772  }
773  if ((corners & (1 << 2)) != 0) {
774  r = +1E20;
775  ir = std::numeric_limits<int64_t>::max();
776  }
777  if ((corners & (1 << 3)) != 0) {
778  b = +1E20;
779  ib = std::numeric_limits<int64_t>::max();
780  }
781 
782  Rect rect = Rect::MakeLTRB(l, t, r, b);
783  IRect irect = IRect::RoundOut(rect);
784  EXPECT_EQ(irect.GetLeft(), il) << corners;
785  EXPECT_EQ(irect.GetTop(), it) << corners;
786  EXPECT_EQ(irect.GetRight(), ir) << corners;
787  EXPECT_EQ(irect.GetBottom(), ib) << corners;
788  };
789 
790  for (int corners = 0; corners <= 15; corners++) {
791  test(corners);
792  }
793 }

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

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

Definition at line 915 of file rect_unittests.cc.

915  {
916  auto test1 = [](Rect rect, Scalar scale) {
917  Rect expected = Rect::MakeXYWH(rect.GetX() * scale, //
918  rect.GetY() * scale, //
919  rect.GetWidth() * scale, //
920  rect.GetHeight() * scale);
921 
922  EXPECT_RECT_NEAR(rect.Scale(scale), expected) //
923  << rect << " * " << scale;
924  EXPECT_RECT_NEAR(rect.Scale(scale, scale), expected) //
925  << rect << " * " << scale;
926  EXPECT_RECT_NEAR(rect.Scale(Point(scale, scale)), expected) //
927  << rect << " * " << scale;
928  EXPECT_RECT_NEAR(rect.Scale(Size(scale, scale)), expected) //
929  << rect << " * " << scale;
930  };
931 
932  auto test2 = [&test1](Rect rect, Scalar scale_x, Scalar scale_y) {
933  Rect expected = Rect::MakeXYWH(rect.GetX() * scale_x, //
934  rect.GetY() * scale_y, //
935  rect.GetWidth() * scale_x, //
936  rect.GetHeight() * scale_y);
937 
938  EXPECT_RECT_NEAR(rect.Scale(scale_x, scale_y), expected) //
939  << rect << " * " << scale_x << ", " << scale_y;
940  EXPECT_RECT_NEAR(rect.Scale(Point(scale_x, scale_y)), expected) //
941  << rect << " * " << scale_x << ", " << scale_y;
942  EXPECT_RECT_NEAR(rect.Scale(Size(scale_x, scale_y)), expected) //
943  << rect << " * " << scale_x << ", " << scale_y;
944 
945  test1(rect, scale_x);
946  test1(rect, scale_y);
947  };
948 
949  test2(Rect::MakeLTRB(10, 15, 100, 150), 1.0, 0.0);
950  test2(Rect::MakeLTRB(10, 15, 100, 150), 0.0, 1.0);
951  test2(Rect::MakeLTRB(10, 15, 100, 150), 0.0, 0.0);
952  test2(Rect::MakeLTRB(10, 15, 100, 150), 2.5, 3.5);
953  test2(Rect::MakeLTRB(10, 15, 100, 150), 3.5, 2.5);
954  test2(Rect::MakeLTRB(10, 15, -100, 150), 2.5, 3.5);
955  test2(Rect::MakeLTRB(10, 15, 100, -150), 2.5, 3.5);
956  test2(Rect::MakeLTRB(10, 15, 100, 150), -2.5, 3.5);
957  test2(Rect::MakeLTRB(10, 15, 100, 150), 2.5, -3.5);
958 }

References EXPECT_RECT_NEAR, impeller::TRect< T >::GetHeight(), impeller::TRect< T >::GetWidth(), impeller::TRect< T >::GetX(), impeller::TRect< T >::GetY(), impeller::TRect< Scalar >::MakeLTRB(), impeller::TRect< Scalar >::MakeXYWH(), impeller::TRect< T >::Scale(), and scale.

◆ TEST() [299/389]

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

Definition at line 2977 of file rect_unittests.cc.

2977  {
2978  auto r = Rect::MakeLTRB(0, 0, 100, 100);
2979 
2980  EXPECT_EQ(r.Shift(Point(10, 5)), Rect::MakeLTRB(10, 5, 110, 105));
2981  EXPECT_EQ(r.Shift(Point(-10, -5)), Rect::MakeLTRB(-10, -5, 90, 95));
2982 }

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

◆ TEST() [300/389]

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

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

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

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

Definition at line 1344 of file rect_unittests.cc.

1344  {
1345  auto check_nans = [](const Rect& a, const Rect& b, const std::string& label) {
1346  ASSERT_TRUE(a.IsFinite()) << label;
1347  ASSERT_TRUE(b.IsFinite()) << label;
1348  ASSERT_FALSE(a.Union(b).IsEmpty());
1349 
1350  for (int i = 1; i < 16; i++) {
1351  // NaN in a produces b
1352  EXPECT_EQ(swap_nan(a, i).Union(b), b) << label << ", index = " << i;
1353  // NaN in b produces a
1354  EXPECT_EQ(a.Union(swap_nan(b, i)), a) << label << ", index = " << i;
1355  // NaN in both is empty
1356  for (int j = 1; j < 16; j++) {
1357  EXPECT_TRUE(swap_nan(a, i).Union(swap_nan(b, j)).IsEmpty())
1358  << label << ", indices = " << i << ", " << j;
1359  }
1360  }
1361  };
1362 
1363  auto check_empty_flips = [](const Rect& a, const Rect& b,
1364  const std::string& label) {
1365  ASSERT_FALSE(a.IsEmpty());
1366  // b is allowed to be empty
1367 
1368  // unflipped a vs flipped (empty) b yields a
1369  EXPECT_EQ(a.Union(flip_lr(b)), a) << label;
1370  EXPECT_EQ(a.Union(flip_tb(b)), a) << label;
1371  EXPECT_EQ(a.Union(flip_lrtb(b)), a) << label;
1372 
1373  // flipped (empty) a vs unflipped b yields b
1374  EXPECT_EQ(flip_lr(a).Union(b), b) << label;
1375  EXPECT_EQ(flip_tb(a).Union(b), b) << label;
1376  EXPECT_EQ(flip_lrtb(a).Union(b), b) << label;
1377 
1378  // flipped (empty) a vs flipped (empty) b yields empty
1379  EXPECT_TRUE(flip_lr(a).Union(flip_lr(b)).IsEmpty()) << label;
1380  EXPECT_TRUE(flip_tb(a).Union(flip_tb(b)).IsEmpty()) << label;
1381  EXPECT_TRUE(flip_lrtb(a).Union(flip_lrtb(b)).IsEmpty()) << label;
1382  };
1383 
1384  auto test = [&check_nans, &check_empty_flips](const Rect& a, const Rect& b,
1385  const Rect& result) {
1386  ASSERT_FALSE(a.IsEmpty()) << a;
1387  // b is allowed to be empty
1388 
1389  std::stringstream stream;
1390  stream << a << " union " << b;
1391  auto label = stream.str();
1392 
1393  EXPECT_EQ(a.Union(b), result) << label;
1394  EXPECT_EQ(b.Union(a), result) << label;
1395  check_empty_flips(a, b, label);
1396  check_nans(a, b, label);
1397  };
1398 
1399  {
1400  auto a = Rect::MakeXYWH(100, 100, 100, 100);
1401  auto b = Rect::MakeXYWH(0, 0, 0, 0);
1402  auto expected = Rect::MakeXYWH(100, 100, 100, 100);
1403  test(a, b, expected);
1404  }
1405 
1406  {
1407  auto a = Rect::MakeXYWH(100, 100, 100, 100);
1408  auto b = Rect::MakeXYWH(0, 0, 1, 1);
1409  auto expected = Rect::MakeXYWH(0, 0, 200, 200);
1410  test(a, b, expected);
1411  }
1412 
1413  {
1414  auto a = Rect::MakeXYWH(100, 100, 100, 100);
1415  auto b = Rect::MakeXYWH(10, 10, 1, 1);
1416  auto expected = Rect::MakeXYWH(10, 10, 190, 190);
1417  test(a, b, expected);
1418  }
1419 
1420  {
1421  auto a = Rect::MakeXYWH(0, 0, 100, 100);
1422  auto b = Rect::MakeXYWH(10, 10, 100, 100);
1423  auto expected = Rect::MakeXYWH(0, 0, 110, 110);
1424  test(a, b, expected);
1425  }
1426 
1427  {
1428  auto a = Rect::MakeXYWH(0, 0, 100, 100);
1429  auto b = Rect::MakeXYWH(100, 100, 100, 100);
1430  auto expected = Rect::MakeXYWH(0, 0, 200, 200);
1431  test(a, b, expected);
1432  }
1433 }

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

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

Definition at line 1158 of file rect_unittests.cc.

1158  {
1159  auto nan = std::numeric_limits<Scalar>::quiet_NaN();
1160 
1161  // Non-empty
1162  EXPECT_FALSE(Rect::MakeXYWH(1.5, 2.3, 10.5, 7.2).IsEmpty());
1163 
1164  // Empty both width and height both 0 or negative, in all combinations
1165  EXPECT_TRUE(Rect::MakeXYWH(1.5, 2.3, 0.0, 0.0).IsEmpty());
1166  EXPECT_TRUE(Rect::MakeXYWH(1.5, 2.3, -1.0, -1.0).IsEmpty());
1167  EXPECT_TRUE(Rect::MakeXYWH(1.5, 2.3, 0.0, -1.0).IsEmpty());
1168  EXPECT_TRUE(Rect::MakeXYWH(1.5, 2.3, -1.0, 0.0).IsEmpty());
1169 
1170  // Empty for 0 or negative width or height (but not both at the same time)
1171  EXPECT_TRUE(Rect::MakeXYWH(1.5, 2.3, 10.5, 0.0).IsEmpty());
1172  EXPECT_TRUE(Rect::MakeXYWH(1.5, 2.3, 10.5, -1.0).IsEmpty());
1173  EXPECT_TRUE(Rect::MakeXYWH(1.5, 2.3, 0.0, 7.2).IsEmpty());
1174  EXPECT_TRUE(Rect::MakeXYWH(1.5, 2.3, -1.0, 7.2).IsEmpty());
1175 
1176  // Empty for NaN in width or height or both
1177  EXPECT_TRUE(Rect::MakeXYWH(1.5, 2.3, 10.5, nan).IsEmpty());
1178  EXPECT_TRUE(Rect::MakeXYWH(1.5, 2.3, nan, 7.2).IsEmpty());
1179  EXPECT_TRUE(Rect::MakeXYWH(1.5, 2.3, nan, nan).IsEmpty());
1180 }

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

◆ TEST() [305/389]

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

Definition at line 3110 of file rect_unittests.cc.

3110  {
3111  {
3112  // This matrix should clip no corners.
3113  auto matrix = impeller::Matrix::MakeColumn(
3114  // clang-format off
3115  2.0f, 0.0f, 0.0f, 0.0f,
3116  0.0f, 4.0f, 0.0f, 0.0f,
3117  0.0f, 0.0f, 1.0f, 0.0f,
3118  0.0f, 0.0f, 0.0f, 8.0f
3119  // clang-format on
3120  );
3121  Rect src = Rect::MakeLTRB(100.0f, 100.0f, 200.0f, 200.0f);
3122  // None of these should have a W<0
3123  EXPECT_EQ(matrix.TransformHomogenous(src.GetLeftTop()),
3124  Vector3(200.0f, 400.0f, 8.0f));
3125  EXPECT_EQ(matrix.TransformHomogenous(src.GetRightTop()),
3126  Vector3(400.0f, 400.0f, 8.0f));
3127  EXPECT_EQ(matrix.TransformHomogenous(src.GetLeftBottom()),
3128  Vector3(200.0f, 800.0f, 8.0f));
3129  EXPECT_EQ(matrix.TransformHomogenous(src.GetRightBottom()),
3130  Vector3(400.0f, 800.0f, 8.0f));
3131 
3132  Rect expect = Rect::MakeLTRB(25.0f, 50.0f, 50.0f, 100.0f);
3133  EXPECT_FALSE(src.TransformAndClipBounds(matrix).IsEmpty());
3134  EXPECT_EQ(src.TransformAndClipBounds(matrix), expect);
3135  }
3136 
3137  {
3138  // This matrix should clip one corner.
3139  auto matrix = impeller::Matrix::MakeColumn(
3140  // clang-format off
3141  2.0f, 0.0f, 0.0f, -0.01f,
3142  0.0f, 2.0f, 0.0f, -0.006f,
3143  0.0f, 0.0f, 1.0f, 0.0f,
3144  0.0f, 0.0f, 0.0f, 3.0f
3145  // clang-format on
3146  );
3147  Rect src = Rect::MakeLTRB(100.0f, 100.0f, 200.0f, 200.0f);
3148  // Exactly one of these should have a W<0
3149  EXPECT_VECTOR3_NEAR(matrix.TransformHomogenous(src.GetLeftTop()),
3150  Vector3(200.0f, 200.0f, 1.4f));
3151  EXPECT_VECTOR3_NEAR(matrix.TransformHomogenous(src.GetRightTop()),
3152  Vector3(400.0f, 200.0f, 0.4f));
3153  EXPECT_VECTOR3_NEAR(matrix.TransformHomogenous(src.GetLeftBottom()),
3154  Vector3(200.0f, 400.0f, 0.8f));
3155  EXPECT_VECTOR3_NEAR(matrix.TransformHomogenous(src.GetRightBottom()),
3156  Vector3(400.0f, 400.0f, -0.2f));
3157 
3158  Rect expect = Rect::MakeLTRB(142.85715f, 142.85715f, 6553600.f, 6553600.f);
3159  EXPECT_FALSE(src.TransformAndClipBounds(matrix).IsEmpty());
3160  EXPECT_RECT_NEAR(src.TransformAndClipBounds(matrix), expect);
3161  }
3162 
3163  {
3164  // This matrix should clip two corners.
3165  auto matrix = impeller::Matrix::MakeColumn(
3166  // clang-format off
3167  2.0f, 0.0f, 0.0f, -.015f,
3168  0.0f, 2.0f, 0.0f, -.006f,
3169  0.0f, 0.0f, 1.0f, 0.0f,
3170  0.0f, 0.0f, 0.0f, 3.0f
3171  // clang-format on
3172  );
3173  Rect src = Rect::MakeLTRB(100.0f, 100.0f, 200.0f, 200.0f);
3174  // Exactly two of these should have a W<0
3175  EXPECT_VECTOR3_NEAR(matrix.TransformHomogenous(src.GetLeftTop()),
3176  Vector3(200.0f, 200.0f, 0.9f));
3177  EXPECT_VECTOR3_NEAR(matrix.TransformHomogenous(src.GetRightTop()),
3178  Vector3(400.0f, 200.0f, -0.6f));
3179  EXPECT_VECTOR3_NEAR(matrix.TransformHomogenous(src.GetLeftBottom()),
3180  Vector3(200.0f, 400.0f, 0.3f));
3181  EXPECT_VECTOR3_NEAR(matrix.TransformHomogenous(src.GetRightBottom()),
3182  Vector3(400.0f, 400.0f, -1.2f));
3183 
3184  Rect expect = Rect::MakeLTRB(222.2222f, 222.2222f, 5898373.f, 6553600.f);
3185  EXPECT_FALSE(src.TransformAndClipBounds(matrix).IsEmpty());
3186  EXPECT_RECT_NEAR(src.TransformAndClipBounds(matrix), expect);
3187  }
3188 
3189  {
3190  // This matrix should clip three corners.
3191  auto matrix = impeller::Matrix::MakeColumn(
3192  // clang-format off
3193  2.0f, 0.0f, 0.0f, -.02f,
3194  0.0f, 2.0f, 0.0f, -.006f,
3195  0.0f, 0.0f, 1.0f, 0.0f,
3196  0.0f, 0.0f, 0.0f, 3.0f
3197  // clang-format on
3198  );
3199  Rect src = Rect::MakeLTRB(100.0f, 100.0f, 200.0f, 200.0f);
3200  // Exactly three of these should have a W<0
3201  EXPECT_VECTOR3_NEAR(matrix.TransformHomogenous(src.GetLeftTop()),
3202  Vector3(200.0f, 200.0f, 0.4f));
3203  EXPECT_VECTOR3_NEAR(matrix.TransformHomogenous(src.GetRightTop()),
3204  Vector3(400.0f, 200.0f, -1.6f));
3205  EXPECT_VECTOR3_NEAR(matrix.TransformHomogenous(src.GetLeftBottom()),
3206  Vector3(200.0f, 400.0f, -0.2f));
3207  EXPECT_VECTOR3_NEAR(matrix.TransformHomogenous(src.GetRightBottom()),
3208  Vector3(400.0f, 400.0f, -2.2f));
3209 
3210  Rect expect = Rect::MakeLTRB(499.99988f, 499.99988f, 5898340.f, 4369400.f);
3211  EXPECT_FALSE(src.TransformAndClipBounds(matrix).IsEmpty());
3212  EXPECT_RECT_NEAR(src.TransformAndClipBounds(matrix), expect);
3213  }
3214 
3215  {
3216  // This matrix should clip all four corners.
3217  auto matrix = impeller::Matrix::MakeColumn(
3218  // clang-format off
3219  2.0f, 0.0f, 0.0f, -.025f,
3220  0.0f, 2.0f, 0.0f, -.006f,
3221  0.0f, 0.0f, 1.0f, 0.0f,
3222  0.0f, 0.0f, 0.0f, 3.0f
3223  // clang-format on
3224  );
3225  Rect src = Rect::MakeLTRB(100.0f, 100.0f, 200.0f, 200.0f);
3226  // All of these should have a W<0
3227  EXPECT_VECTOR3_NEAR(matrix.TransformHomogenous(src.GetLeftTop()),
3228  Vector3(200.0f, 200.0f, -0.1f));
3229  EXPECT_VECTOR3_NEAR(matrix.TransformHomogenous(src.GetRightTop()),
3230  Vector3(400.0f, 200.0f, -2.6f));
3231  EXPECT_VECTOR3_NEAR(matrix.TransformHomogenous(src.GetLeftBottom()),
3232  Vector3(200.0f, 400.0f, -0.7f));
3233  EXPECT_VECTOR3_NEAR(matrix.TransformHomogenous(src.GetRightBottom()),
3234  Vector3(400.0f, 400.0f, -3.2f));
3235 
3236  EXPECT_TRUE(src.TransformAndClipBounds(matrix).IsEmpty());
3237  }
3238 }

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

impeller::testing::TEST ( RenderPassBuilder  ,
CreatesMSAAResolveWithCorrectStore   
)

Definition at line 102 of file render_pass_builder_vk_unittests.cc.

102  {
103  RenderPassBuilderVK builder = RenderPassBuilderVK();
104  auto const context = MockVulkanContextBuilder().Build();
105 
106  // Create an MSAA color attachment.
107  builder.SetColorAttachment(0, PixelFormat::kR8G8B8A8UNormInt,
108  SampleCount::kCount4, LoadAction::kClear,
109  StoreAction::kMultisampleResolve);
110 
111  auto render_pass = builder.Build(context->GetDevice());
112 
113  EXPECT_TRUE(!!render_pass);
114 
115  auto maybe_color = builder.GetColorAttachments().find(0u);
116  ASSERT_NE(maybe_color, builder.GetColorAttachments().end());
117  auto color = maybe_color->second;
118 
119  // MSAA Texture.
120  EXPECT_EQ(color.initialLayout, vk::ImageLayout::eGeneral);
121  EXPECT_EQ(color.finalLayout, vk::ImageLayout::eGeneral);
122  EXPECT_EQ(color.loadOp, vk::AttachmentLoadOp::eClear);
123  EXPECT_EQ(color.storeOp, vk::AttachmentStoreOp::eDontCare);
124 
125  auto maybe_resolve = builder.GetResolves().find(0u);
126  ASSERT_NE(maybe_resolve, builder.GetResolves().end());
127  auto resolve = maybe_resolve->second;
128 
129  // MSAA Resolve Texture.
130  EXPECT_EQ(resolve.initialLayout, vk::ImageLayout::eGeneral);
131  EXPECT_EQ(resolve.finalLayout, vk::ImageLayout::eGeneral);
132  EXPECT_EQ(resolve.loadOp, vk::AttachmentLoadOp::eClear);
133  EXPECT_EQ(resolve.storeOp, vk::AttachmentStoreOp::eStore);
134 }

References impeller::RenderPassBuilderVK::Build(), color, impeller::RenderPassBuilderVK::GetColorAttachments(), impeller::RenderPassBuilderVK::GetResolves(), impeller::kClear, impeller::kCount4, impeller::kMultisampleResolve, impeller::kR8G8B8A8UNormInt, and impeller::RenderPassBuilderVK::SetColorAttachment().

◆ TEST() [307/389]

impeller::testing::TEST ( RenderPassBuilder  ,
CreatesRenderPassWithCombinedDepthStencil   
)

Definition at line 30 of file render_pass_builder_vk_unittests.cc.

30  {
31  RenderPassBuilderVK builder = RenderPassBuilderVK();
32  auto const context = MockVulkanContextBuilder().Build();
33 
34  // Create a single color attachment with a transient depth stencil.
35  builder.SetColorAttachment(0, PixelFormat::kR8G8B8A8UNormInt,
36  SampleCount::kCount1, LoadAction::kClear,
37  StoreAction::kStore);
38  builder.SetDepthStencilAttachment(PixelFormat::kD24UnormS8Uint,
39  SampleCount::kCount1, LoadAction::kDontCare,
40  StoreAction::kDontCare);
41 
42  auto render_pass = builder.Build(context->GetDevice());
43 
44  EXPECT_TRUE(!!render_pass);
45 
46  auto maybe_color = builder.GetColorAttachments().find(0u);
47  ASSERT_NE(maybe_color, builder.GetColorAttachments().end());
48  auto color = maybe_color->second;
49 
50  EXPECT_EQ(color.initialLayout, vk::ImageLayout::eGeneral);
51  EXPECT_EQ(color.finalLayout, vk::ImageLayout::eGeneral);
52  EXPECT_EQ(color.loadOp, vk::AttachmentLoadOp::eClear);
53  EXPECT_EQ(color.storeOp, vk::AttachmentStoreOp::eStore);
54 
55  auto maybe_depth_stencil = builder.GetDepthStencil();
56  ASSERT_TRUE(maybe_depth_stencil.has_value());
57  if (!maybe_depth_stencil.has_value()) {
58  return;
59  }
60  auto depth_stencil = maybe_depth_stencil.value();
61 
62  EXPECT_EQ(depth_stencil.initialLayout, vk::ImageLayout::eUndefined);
63  EXPECT_EQ(depth_stencil.finalLayout,
64  vk::ImageLayout::eDepthStencilAttachmentOptimal);
65  EXPECT_EQ(depth_stencil.loadOp, vk::AttachmentLoadOp::eDontCare);
66  EXPECT_EQ(depth_stencil.storeOp, vk::AttachmentStoreOp::eDontCare);
67  EXPECT_EQ(depth_stencil.stencilLoadOp, vk::AttachmentLoadOp::eDontCare);
68  EXPECT_EQ(depth_stencil.stencilStoreOp, vk::AttachmentStoreOp::eDontCare);
69 }

References impeller::RenderPassBuilderVK::Build(), color, impeller::RenderPassBuilderVK::GetColorAttachments(), impeller::RenderPassBuilderVK::GetDepthStencil(), impeller::kClear, impeller::kCount1, impeller::kD24UnormS8Uint, impeller::kDontCare, impeller::kR8G8B8A8UNormInt, impeller::kStore, impeller::RenderPassBuilderVK::SetColorAttachment(), and impeller::RenderPassBuilderVK::SetDepthStencilAttachment().

◆ TEST() [308/389]

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

impeller::testing::TEST ( RenderPassBuilder  ,
CreatesRenderPassWithOnlyStencil   
)

Definition at line 71 of file render_pass_builder_vk_unittests.cc.

71  {
72  RenderPassBuilderVK builder = RenderPassBuilderVK();
73  auto const context = MockVulkanContextBuilder().Build();
74 
75  // Create a single color attachment with a transient depth stencil.
76  builder.SetColorAttachment(0, PixelFormat::kR8G8B8A8UNormInt,
77  SampleCount::kCount1, LoadAction::kClear,
78  StoreAction::kStore);
79  builder.SetStencilAttachment(PixelFormat::kS8UInt, SampleCount::kCount1,
80  LoadAction::kDontCare, StoreAction::kDontCare);
81 
82  auto render_pass = builder.Build(context->GetDevice());
83 
84  EXPECT_TRUE(!!render_pass);
85 
86  auto maybe_depth_stencil = builder.GetDepthStencil();
87  ASSERT_TRUE(maybe_depth_stencil.has_value());
88  if (!maybe_depth_stencil.has_value()) {
89  return;
90  }
91  auto depth_stencil = maybe_depth_stencil.value();
92 
93  EXPECT_EQ(depth_stencil.initialLayout, vk::ImageLayout::eUndefined);
94  EXPECT_EQ(depth_stencil.finalLayout,
95  vk::ImageLayout::eDepthStencilAttachmentOptimal);
96  EXPECT_EQ(depth_stencil.loadOp, vk::AttachmentLoadOp::eDontCare);
97  EXPECT_EQ(depth_stencil.storeOp, vk::AttachmentStoreOp::eDontCare);
98  EXPECT_EQ(depth_stencil.stencilLoadOp, vk::AttachmentLoadOp::eDontCare);
99  EXPECT_EQ(depth_stencil.stencilStoreOp, vk::AttachmentStoreOp::eDontCare);
100 }

References impeller::RenderPassBuilderVK::Build(), impeller::RenderPassBuilderVK::GetDepthStencil(), impeller::kClear, impeller::kCount1, impeller::kDontCare, impeller::kR8G8B8A8UNormInt, impeller::kS8UInt, impeller::kStore, impeller::RenderPassBuilderVK::SetColorAttachment(), and impeller::RenderPassBuilderVK::SetStencilAttachment().

◆ TEST() [310/389]

impeller::testing::TEST ( ResourceManagerVKTest  ,
CreatesANewInstance   
)

Definition at line 18 of file resource_manager_vk_unittests.cc.

18  {
19  auto const a = ResourceManagerVK::Create();
20  auto const b = ResourceManagerVK::Create();
21  EXPECT_NE(a, b);
22 }

References impeller::saturated::b, and impeller::ResourceManagerVK::Create().

◆ TEST() [311/389]

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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 }

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

◆ TEST() [333/389]

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

impeller::testing::TEST ( ShaderArchiveTest  ,
CanReadAndWriteBlobs   
)

Definition at line 28 of file shader_archive_unittests.cc.

28  {
29  ShaderArchiveWriter writer;
30  ASSERT_TRUE(writer.AddShader(ArchiveShaderType::kVertex, "Hello",
31  CreateMappingFromString("World")));
32  ASSERT_TRUE(writer.AddShader(ArchiveShaderType::kFragment, "Foo",
33  CreateMappingFromString("Bar")));
34  ASSERT_TRUE(writer.AddShader(ArchiveShaderType::kVertex, "Baz",
35  CreateMappingFromString("Bang")));
36  ASSERT_TRUE(writer.AddShader(ArchiveShaderType::kVertex, "Ping",
37  CreateMappingFromString("Pong")));
38  ASSERT_TRUE(writer.AddShader(ArchiveShaderType::kFragment, "Pang",
39  CreateMappingFromString("World")));
40 
41  auto mapping = writer.CreateMapping();
42  ASSERT_NE(mapping, nullptr);
43 
44  ShaderArchive library(mapping);
45  ASSERT_TRUE(library.IsValid());
46  ASSERT_EQ(library.GetShaderCount(), 5u);
47 
48  // Wrong type.
49  ASSERT_EQ(library.GetMapping(ArchiveShaderType::kFragment, "Hello"), nullptr);
50 
51  auto hello_vtx = library.GetMapping(ArchiveShaderType::kVertex, "Hello");
52  ASSERT_NE(hello_vtx, nullptr);
53  ASSERT_EQ(CreateStringFromMapping(*hello_vtx), "World");
54 }

References impeller::ShaderArchiveWriter::AddShader(), impeller::ShaderArchiveWriter::CreateMapping(), CreateMappingFromString(), CreateStringFromMapping(), impeller::ShaderArchive::GetMapping(), impeller::ShaderArchive::GetShaderCount(), impeller::ShaderArchive::IsValid(), impeller::kFragment, and impeller::kVertex.

◆ TEST() [350/389]

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

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

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

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

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

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 }

References impeller::skia_conversions::ToBlendMode().

◆ TEST() [356/389]

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(SkPoint::Make(0, 0), //
241  SkPoint::Make(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.get(), 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 }

References impeller::skia_conversions::ConvertStops(), and impeller::ScalarNearlyEqual().

◆ TEST() [357/389]

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(SkPoint::Make(0, 0), //
162  SkPoint::Make(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.get(), 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() [358/389]

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(SkPoint::Make(0, 0), //
188  SkPoint::Make(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.get(), 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() [359/389]

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(SkPoint::Make(0, 0), //
138  SkPoint::Make(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.get(), 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() [360/389]

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(SkPoint::Make(0, 0), //
215  SkPoint::Make(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.get(), 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() [361/389]

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 }

References impeller::skia_conversions::IsNearlySimpleRRect(), and impeller::kEhCloseEnough.

◆ TEST() [362/389]

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 }

References impeller::skia_conversions::ToPoint().

◆ TEST() [363/389]

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 }

References impeller::skia_conversions::ToSize().

◆ TEST() [364/389]

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 }

References color, impeller::ScalarNearlyEqual(), and impeller::skia_conversions::ToColor().

◆ TEST() [365/389]

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 }

References impeller::Matrix::IsTranslationScaleOnly(), impeller::skia_conversions::ToMatrix(), and impeller::Matrix::vec.

◆ TEST() [366/389]

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

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

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

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 }

References impeller::kBase, impeller::kLinear, impeller::kNearest, and impeller::skia_conversions::ToSamplerDescriptor().

◆ TEST() [370/389]

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 }

References impeller::SPrintF().

◆ TEST() [371/389]

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

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

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

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

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

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

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

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

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

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

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

impeller::testing::TEST ( TextureMTL  ,
CreateFromDrawable   
)

Definition at line 21 of file texture_mtl_unittests.mm.

21  {
22  auto device = MTLCreateSystemDefaultDevice();
23  auto layer = [[CAMetalLayer alloc] init];
24  layer.device = device;
25  layer.drawableSize = CGSize{100, 100};
26  layer.pixelFormat = ToMTLPixelFormat(PixelFormat::kB8G8R8A8UNormInt);
27 
28  TextureDescriptor desc;
29  desc.size = {100, 100};
30  desc.format = PixelFormat::kB8G8R8A8UNormInt;
31  auto drawable_future = GetDrawableDeferred(layer);
32  auto drawable_texture =
33  CreateTextureFromDrawableFuture(desc, drawable_future);
34 
35  ASSERT_TRUE(drawable_texture->IsValid());
36  EXPECT_TRUE(drawable_texture->IsDrawable());
37 
38  // Spawn a thread and acquire the drawable in the thread.
39  auto thread = std::thread([&drawable_texture]() {
40  // Force the drawable to be acquired.
41  drawable_texture->GetMTLTexture();
42  });
43  thread.join();
44  // Block until drawable is acquired.
45  EXPECT_TRUE(drawable_future.get() != nil);
46  // Drawable is cached.
47  EXPECT_TRUE(drawable_texture->GetMTLTexture() != nil);
48  // Once more for good measure.
49  EXPECT_TRUE(drawable_texture->GetMTLTexture() != nil);
50 }

References impeller::CreateTextureFromDrawableFuture(), impeller::TextureDescriptor::format, impeller::GetDrawableDeferred(), impeller::kB8G8R8A8UNormInt, impeller::TextureDescriptor::size, and impeller::ToMTLPixelFormat().

◆ TEST() [383/389]

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

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

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

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

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

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

impeller::testing::TEST ( TypographerTest  ,
RectanglePackerFillsRows   
)

Definition at line 398 of file typographer_unittests.cc.

398  {
399  auto skyline = RectanglePacker::Factory(257, 256);
400 
401  // Fill up the first row.
402  IPoint16 loc;
403  for (auto i = 0u; i < 16; i++) {
404  skyline->AddRect(16, 16, &loc);
405  }
406  // Last rectangle still in first row.
407  EXPECT_EQ(loc.x(), 256 - 16);
408  EXPECT_EQ(loc.y(), 0);
409 
410  // Fill up second row.
411  for (auto i = 0u; i < 16; i++) {
412  skyline->AddRect(16, 16, &loc);
413  }
414 
415  EXPECT_EQ(loc.x(), 256 - 16);
416  EXPECT_EQ(loc.y(), 16);
417 }

References impeller::RectanglePacker::Factory(), impeller::IPoint16::x(), and impeller::IPoint16::y().

◆ TEST_F()

impeller::testing::TEST_F ( GoldenTests  ,
ConicalGradient   
)

Definition at line 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::DlConicalGradientColorSource::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 }

References impeller::DisplayListToTexture(), and impeller::testing::Screenshotter::MakeScreenshot().

◆ TEST_P() [1/454]

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 }

◆ TEST_P() [2/454]

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

Definition at line 895 of file aiks_dl_unittests.cc.

895  {
896  DisplayListBuilder builder;
897 
898  DlPaint paint;
899  // Add a difference clip that cuts out the bottom right corner
900  builder.ClipRect(SkRect::MakeLTRB(50, 50, 100, 100),
901  DlCanvas::ClipOp::kDifference);
902 
903  // Draw a red rectangle that's going to be completely covered by green later.
904  paint.setColor(DlColor::kRed());
905  builder.DrawRect(SkRect::MakeLTRB(0, 0, 100, 100), paint);
906 
907  // Add a clip restricting the backdrop filter to the top right corner.
908  auto count = builder.GetSaveCount();
909  builder.Save();
910  {
911  builder.ClipRect(SkRect::MakeLTRB(0, 0, 100, 100));
912  {
913  // Create a save layer with a backdrop blur filter.
914  auto backdrop_filter =
915  DlBlurImageFilter::Make(10.0, 10.0, DlTileMode::kDecal);
916  builder.SaveLayer(nullptr, nullptr, backdrop_filter.get());
917  }
918  }
919  builder.RestoreToCount(count);
920 
921  // Finally, overwrite all the previous stuff with green.
922  paint.setColor(DlColor::kGreen());
923  builder.DrawRect(SkRect::MakeLTRB(0, 0, 100, 100), paint);
924 
925  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
926 }

◆ TEST_P() [3/454]

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

Definition at line 432 of file aiks_dl_blend_unittests.cc.

432  {
433  EXPECT_EQ(GetContext()->GetCapabilities()->GetDefaultColorFormat(),
434  PixelFormat::kB10G10R10A10XR);
435  auto texture = CreateTextureForFixture("airplane.jpg",
436  /*enable_mipmapping=*/true);
437 
438  DisplayListBuilder builder;
439  builder.Scale(GetContentScale().x, GetContentScale().y);
440 
441  DlPaint paint;
442  paint.setColor(DlColor::RGBA(0.1, 0.2, 0.1, 1.0));
443  builder.DrawPaint(paint);
444 
445  DlPaint save_paint;
446  save_paint.setColorFilter(
447  DlBlendColorFilter::Make(DlColor::RGBA(1, 0, 0, 1), DlBlendMode::kPlus));
448  builder.SaveLayer(nullptr, &save_paint);
449 
450  paint.setColor(DlColor::kRed());
451  builder.DrawRect(SkRect::MakeXYWH(100, 100, 400, 400), paint);
452 
453  paint.setColor(DlColor::kWhite());
454 
455  auto rect = Rect::MakeXYWH(100, 100, 400, 400).Expand(-100, -100);
456  builder.DrawImageRect(
457  DlImageImpeller::Make(texture),
458  SkRect::MakeSize(
459  SkSize::Make(texture->GetSize().width, texture->GetSize().height)),
460  SkRect::MakeLTRB(rect.GetLeft(), rect.GetTop(), rect.GetRight(),
461  rect.GetBottom()),
462  DlImageSampling::kMipmapLinear, &paint);
463  builder.Restore();
464 
465  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
466 }

References impeller::TRect< T >::Expand(), impeller::kB10G10R10A10XR, impeller::DlImageImpeller::Make(), and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST_P() [4/454]

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

Definition at line 399 of file aiks_dl_blend_unittests.cc.

399  {
400  EXPECT_EQ(GetContext()->GetCapabilities()->GetDefaultColorFormat(),
401  PixelFormat::kB10G10R10A10XR);
402  auto texture = CreateTextureForFixture("airplane.jpg",
403  /*enable_mipmapping=*/true);
404 
405  DisplayListBuilder builder;
406  DlPaint paint;
407  builder.Scale(GetContentScale().x, GetContentScale().y);
408 
409  paint.setColor(DlColor::RGBA(0.9, 1, 0.9, 1.0));
410  builder.DrawPaint(paint);
411  builder.SaveLayer(nullptr);
412 
413  paint.setBlendMode(DlBlendMode::kPlus);
414  paint.setColor(DlColor::kRed());
415 
416  builder.DrawRect(SkRect::MakeXYWH(100, 100, 400, 400), paint);
417  paint.setColor(DlColor::kWhite());
418 
419  auto rect = Rect::MakeXYWH(100, 100, 400, 400).Expand(-100, -100);
420  builder.DrawImageRect(
421  DlImageImpeller::Make(texture),
422  SkRect::MakeSize(
423  SkSize::Make(texture->GetSize().width, texture->GetSize().height)),
424  SkRect::MakeLTRB(rect.GetLeft(), rect.GetTop(), rect.GetRight(),
425  rect.GetBottom()),
426  DlImageSampling::kMipmapLinear, &paint);
427  builder.Restore();
428  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
429 }

References impeller::TRect< T >::Expand(), impeller::kB10G10R10A10XR, impeller::DlImageImpeller::Make(), and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST_P() [5/454]

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

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

Definition at line 358 of file aiks_dl_blur_unittests.cc.

358  {
359  Scalar sigma = 47.6;
360  auto callback = [&]() -> sk_sp<DisplayList> {
361  if (AiksTest::ImGuiBegin("Controls", nullptr,
362  ImGuiWindowFlags_AlwaysAutoResize)) {
363  ImGui::SliderFloat("Sigma", &sigma, 0, 50);
364  ImGui::End();
365  }
366  DisplayListBuilder builder;
367  builder.Scale(GetContentScale().x, GetContentScale().y);
368  builder.DrawPaint({});
369 
370  DlPaint paint;
371  paint.setColor(DlColor::kGreen());
372  paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kNormal, sigma));
373 
374  builder.DrawRect(SkRect::MakeXYWH(300, 300, 200, 200), paint);
375  return builder.Build();
376  };
377 
378  ASSERT_TRUE(OpenPlaygroundHere(callback));
379 }

References impeller::AiksPlayground::ImGuiBegin().

◆ TEST_P() [7/454]

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

Definition at line 1096 of file aiks_dl_blur_unittests.cc.

1096  {
1097  DisplayListBuilder builder;
1098  builder.Scale(GetContentScale().x, GetContentScale().y);
1099 
1100  auto paint_lines = [&builder](Scalar dx, Scalar dy, DlPaint paint) {
1101  auto draw_line = [&builder, &paint](SkPoint a, SkPoint b) {
1102  SkPath line = SkPath::Line(a, b);
1103  builder.DrawPath(line, paint);
1104  };
1105  paint.setStrokeWidth(5);
1106  paint.setDrawStyle(DlDrawStyle::kStroke);
1107  draw_line(SkPoint::Make(dx + 100, dy + 100),
1108  SkPoint::Make(dx + 200, dy + 200));
1109  draw_line(SkPoint::Make(dx + 100, dy + 200),
1110  SkPoint::Make(dx + 200, dy + 100));
1111  draw_line(SkPoint::Make(dx + 150, dy + 100),
1112  SkPoint::Make(dx + 200, dy + 150));
1113  draw_line(SkPoint::Make(dx + 100, dy + 150),
1114  SkPoint::Make(dx + 150, dy + 200));
1115  };
1116 
1117  AiksContext renderer(GetContext(), nullptr);
1118  DisplayListBuilder recorder_builder;
1119  for (int x = 0; x < 5; ++x) {
1120  for (int y = 0; y < 5; ++y) {
1121  SkRect rect = SkRect::MakeXYWH(x * 20, y * 20, 20, 20);
1122  DlPaint paint;
1123  paint.setColor(((x + y) & 1) == 0 ? DlColor::kYellow()
1124  : DlColor::kBlue());
1125 
1126  recorder_builder.DrawRect(rect, paint);
1127  }
1128  }
1129  auto texture =
1130  DisplayListToTexture(recorder_builder.Build(), {100, 100}, renderer);
1131 
1132  auto image_source = std::make_shared<DlImageColorSource>(
1133  DlImageImpeller::Make(texture), DlTileMode::kRepeat, DlTileMode::kRepeat);
1134  auto blur_filter = DlBlurImageFilter::Make(5, 5, DlTileMode::kDecal);
1135 
1136  DlPaint paint;
1137  paint.setColor(DlColor::kDarkGreen());
1138  builder.DrawRect(SkRect::MakeLTRB(0, 0, 300, 600), paint);
1139 
1140  paint.setColorSource(image_source);
1141  builder.DrawRect(SkRect::MakeLTRB(100, 100, 200, 200), paint);
1142 
1143  paint.setColorSource(nullptr);
1144  paint.setColor(DlColor::kRed());
1145  builder.DrawRect(SkRect::MakeLTRB(300, 0, 600, 600), paint);
1146 
1147  paint.setColorSource(image_source);
1148  paint.setImageFilter(blur_filter);
1149  builder.DrawRect(SkRect::MakeLTRB(400, 100, 500, 200), paint);
1150 
1151  paint.setImageFilter(nullptr);
1152  paint_lines(0, 300, paint);
1153 
1154  paint.setImageFilter(blur_filter);
1155  paint_lines(300, 300, paint);
1156 
1157  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1158 }

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

◆ TEST_P() [8/454]

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

Definition at line 154 of file aiks_dl_vertices_unittests.cc.

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

◆ TEST_P() [9/454]

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

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

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

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

Definition at line 392 of file aiks_dl_basic_unittests.cc.

392  {
393  auto medium_turquoise =
394  DlColor::RGBA(72.0f / 255.0f, 209.0f / 255.0f, 204.0f / 255.0f, 1.0f);
395 
396  DisplayListBuilder builder;
397  builder.Scale(0.2, 0.2);
398  builder.DrawPaint(DlPaint().setColor(medium_turquoise));
399  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
400 }

◆ TEST_P() [13/454]

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

Definition at line 402 of file aiks_dl_basic_unittests.cc.

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

◆ TEST_P() [14/454]

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

Definition at line 683 of file aiks_dl_blend_unittests.cc.

683  {
684  auto modes = GetBlendModeSelection();
685 
686  auto callback = [&]() -> sk_sp<DisplayList> {
687  static Color background = Color::MediumTurquoise();
688  static Color foreground = Color::Color::OrangeRed().WithAlpha(0.5);
689  static int current_blend_index = 3;
690 
691  if (AiksTest::ImGuiBegin("Controls", nullptr,
692  ImGuiWindowFlags_AlwaysAutoResize)) {
693  ImGui::ColorEdit4("Background", reinterpret_cast<float*>(&background));
694  ImGui::ColorEdit4("Foreground", reinterpret_cast<float*>(&foreground));
695  ImGui::ListBox("Blend mode", &current_blend_index,
696  modes.blend_mode_names.data(),
697  modes.blend_mode_names.size());
698  ImGui::End();
699  }
700 
701  DisplayListBuilder builder;
702  builder.Scale(0.2, 0.2);
703  DlPaint paint;
704  paint.setColor(DlColor(background.ToARGB()));
705  builder.DrawPaint(paint);
706 
707  paint.setColor(DlColor(foreground.ToARGB()));
708  paint.setBlendMode(static_cast<DlBlendMode>(current_blend_index));
709  builder.DrawPaint(paint);
710  return builder.Build();
711  };
712  ASSERT_TRUE(OpenPlaygroundHere(callback));
713 }

References GetBlendModeSelection(), impeller::AiksPlayground::ImGuiBegin(), impeller::Color::MediumTurquoise(), impeller::Color::ToARGB(), and impeller::Color::WithAlpha().

◆ TEST_P() [15/454]

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

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

Definition at line 825 of file aiks_dl_basic_unittests.cc.

825  {
826  // Avoiding `GetSecondsElapsed()` to reduce risk of golden flakiness.
827  int time = 0;
828  auto callback = [&]() -> sk_sp<DisplayList> {
829  DisplayListBuilder builder;
830 
831  builder.Save();
832  {
833  builder.Translate(300, 300);
834 
835  // 1. Draw/restore a clip before drawing the image, which will get drawn
836  // to the depth buffer behind the image.
837  builder.Save();
838  {
839  DlPaint paint;
840  paint.setColor(DlColor::kGreen());
841  builder.DrawPaint(paint);
842  builder.ClipRect(SkRect::MakeLTRB(-180, -180, 180, 180),
843  DlCanvas::ClipOp::kDifference);
844 
845  paint.setColor(DlColor::kBlack());
846  builder.DrawPaint(paint);
847  }
848  builder.Restore(); // Restore rectangle difference clip.
849 
850  builder.Save();
851  {
852  // 2. Draw an oval clip that applies to the image, which will get drawn
853  // in front of the image on the depth buffer.
854  builder.ClipOval(SkRect::MakeLTRB(-200, -200, 200, 200));
855 
856  Matrix result =
857  Matrix(1.0, 0.0, 0.0, 0.0, //
858  0.0, 1.0, 0.0, 0.0, //
859  0.0, 0.0, 1.0, 0.003, //
860  0.0, 0.0, 0.0, 1.0) *
861  Matrix::MakeRotationY({Radians{-1.0f + (time++ / 60.0f)}});
862 
863  // 3. Draw the rotating image with a perspective transform.
864  builder.Transform(FromImpellerMatrix(result));
865 
866  auto image =
867  DlImageImpeller::Make(CreateTextureForFixture("airplane.jpg"));
868  auto position = -SkPoint::Make(image->dimensions().fWidth,
869  image->dimensions().fHeight) *
870  0.5;
871  builder.DrawImage(image, position, {});
872  }
873  builder.Restore(); // Restore oval intersect clip.
874 
875  // 4. Draw a semi-translucent blue circle atop all previous draws.
876  DlPaint paint;
877  paint.setColor(DlColor::kBlue().modulateOpacity(0.4));
878  builder.DrawCircle({}, 230, paint);
879  }
880  builder.Restore(); // Restore translation.
881 
882  return builder.Build();
883  };
884  ASSERT_TRUE(OpenPlaygroundHere(callback));
885 }

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

◆ TEST_P() [17/454]

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

Definition at line 396 of file aiks_dl_unittests.cc.

396  {
397  std::vector<SkPoint> points = {
398  {0, 0}, //
399  {100, 100}, //
400  {100, 0}, //
401  {0, 100}, //
402  {0, 0}, //
403  {48, 48}, //
404  {52, 52}, //
405  };
406  DlPaint paint_round;
407  paint_round.setColor(DlColor::kYellow().withAlpha(128));
408  paint_round.setStrokeCap(DlStrokeCap::kRound);
409  paint_round.setStrokeWidth(20);
410 
411  DlPaint paint_square;
412  paint_square.setColor(DlColor::kYellow().withAlpha(128));
413  paint_square.setStrokeCap(DlStrokeCap::kSquare);
414  paint_square.setStrokeWidth(20);
415 
416  DlPaint background;
417  background.setColor(DlColor::kBlack());
418 
419  DisplayListBuilder builder(GetCullRect(GetWindowSize()));
420  builder.DrawPaint(background);
421  builder.Translate(200, 200);
422 
423  builder.DrawPoints(DlCanvas::PointMode::kPoints, points.size(), points.data(),
424  paint_round);
425  builder.Translate(150, 0);
426  builder.DrawPoints(DlCanvas::PointMode::kPoints, points.size(), points.data(),
427  paint_square);
428 
429  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
430 }

◆ TEST_P() [18/454]

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

Definition at line 432 of file aiks_dl_unittests.cc.

432  {
433  auto texture = DlImageImpeller::Make(
434  CreateTextureForFixture("table_mountain_nx.png",
435  /*enable_mipmapping=*/true));
436 
437  std::vector<SkPoint> points = {
438  {0, 0}, //
439  {100, 100}, //
440  {100, 0}, //
441  {0, 100}, //
442  {0, 0}, //
443  {48, 48}, //
444  {52, 52}, //
445  };
446 
447  auto image_src = std::make_shared<DlImageColorSource>(
448  texture, DlTileMode::kClamp, DlTileMode::kClamp);
449 
450  DlPaint paint_round;
451  paint_round.setStrokeCap(DlStrokeCap::kRound);
452  paint_round.setColorSource(image_src);
453  paint_round.setStrokeWidth(200);
454 
455  DlPaint paint_square;
456  paint_square.setStrokeCap(DlStrokeCap::kSquare);
457  paint_square.setColorSource(image_src);
458  paint_square.setStrokeWidth(200);
459 
460  DisplayListBuilder builder(GetCullRect(GetWindowSize()));
461  builder.Translate(200, 200);
462 
463  builder.DrawPoints(DlCanvas::PointMode::kPoints, points.size(), points.data(),
464  paint_round);
465  builder.Translate(150, 0);
466  builder.DrawPoints(DlCanvas::PointMode::kPoints, points.size(), points.data(),
467  paint_square);
468 
469  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
470 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [19/454]

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

Definition at line 832 of file aiks_dl_unittests.cc.

832  {
833  std::vector<SkPoint> point = {
834  {0, 0}, //
835  };
836 
837  DlPaint paint;
838  paint.setStrokeCap(DlStrokeCap::kRound);
839  paint.setColor(DlColor::kRed());
840  paint.setStrokeWidth(100 * 0.000001);
841 
842  DisplayListBuilder builder(GetCullRect(GetWindowSize()));
843  builder.Translate(200, 200);
844  builder.Scale(1000000, 1000000);
845 
846  builder.DrawPoints(DlCanvas::PointMode::kPoints, point.size(), point.data(),
847  paint);
848  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
849 }

◆ TEST_P() [20/454]

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

Definition at line 811 of file aiks_dl_unittests.cc.

811  {
812  std::vector<SkPoint> point = {
813  {0, 0}, //
814  };
815 
816  DlPaint paint;
817  paint.setStrokeCap(DlStrokeCap::kRound);
818  paint.setColor(DlColor::kRed());
819  paint.setStrokeWidth(100 * 1000000);
820 
821  DisplayListBuilder builder(GetCullRect(GetWindowSize()));
822  builder.Translate(200, 200);
823  builder.Scale(0.000001, 0.000001);
824 
825  builder.DrawPoints(DlCanvas::PointMode::kPoints, point.size(), point.data(),
826  paint);
827 
828  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
829 }

◆ TEST_P() [21/454]

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

Definition at line 955 of file aiks_dl_unittests.cc.

955  {
956  DisplayListBuilder recorder_builder;
957 
958  DisplayListBuilder builder;
959  AiksContext renderer(GetContext(), nullptr);
960 
961  DlPaint paint;
962  paint.setColor(DlColor::kTransparent());
963  builder.DrawPaint(paint);
964 
965  auto result_image =
966  DisplayListToTexture(builder.Build(), ISize{1000, 1000}, renderer);
967  if (result_image) {
968  recorder_builder.DrawImage(DlImageImpeller::Make(result_image), {}, {});
969 
970  paint.setColor(DlColor::RGBA(0.1, 0.1, 0.1, 0.2));
971  recorder_builder.DrawRect(SkRect::MakeSize({1000, 1000}), paint);
972  }
973 
974  ASSERT_TRUE(OpenPlaygroundHere(recorder_builder.Build()));
975 }

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

◆ TEST_P() [22/454]

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

Definition at line 1150 of file aiks_dl_basic_unittests.cc.

1150  {
1151  DisplayListBuilder builder;
1152 
1153  DlPaint paint;
1154  paint.setColor(DlColor::kRed());
1155  builder.DrawCircle(SkPoint::Make(250, 250), 125, paint);
1156 
1157  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1158 }

◆ TEST_P() [23/454]

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

Definition at line 1171 of file aiks_dl_basic_unittests.cc.

1171  {
1172  DisplayListBuilder builder;
1173 
1174  DlPaint save;
1175  save.setColor(DlColor::kBlack());
1176 
1177  SkRect save_bounds = SkRect::MakeXYWH(0, 0, 50, 50);
1178  builder.SaveLayer(&save_bounds, &save);
1179 
1180  DlPaint paint;
1181  paint.setColor(DlColor::kRed());
1182  builder.DrawRect(SkRect::MakeXYWH(0, 0, 100, 100), paint);
1183  paint.setColor(DlColor::kGreen());
1184  builder.DrawRect(SkRect::MakeXYWH(10, 10, 100, 100), paint);
1185  paint.setColor(DlColor::kBlue());
1186  builder.DrawRect(SkRect::MakeXYWH(20, 20, 100, 100), paint);
1187 
1188  builder.Restore();
1189 
1190  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1191 }

◆ TEST_P() [24/454]

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

Definition at line 1072 of file aiks_dl_basic_unittests.cc.

1073  {
1074  DisplayListBuilder builder;
1075 
1076  DlPaint red;
1077  red.setColor(DlColor::kRed());
1078 
1079  DlPaint green;
1080  green.setColor(DlColor::kGreen());
1081 
1082  DlPaint blue;
1083  blue.setColor(DlColor::kBlue());
1084 
1085  DlPaint save;
1086  save.setColor(DlColor::kBlack().modulateOpacity(0.5));
1087 
1088  SkRect huge_bounds = SkRect::MakeXYWH(0, 0, 100000, 100000);
1089  builder.SaveLayer(&huge_bounds, &save);
1090 
1091  builder.DrawRect(SkRect::MakeXYWH(0, 0, 100, 100), red);
1092  builder.DrawRect(SkRect::MakeXYWH(10, 10, 100, 100), green);
1093  builder.DrawRect(SkRect::MakeXYWH(20, 20, 100, 100), blue);
1094 
1095  builder.Restore();
1096 
1097  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1098 }

◆ TEST_P() [25/454]

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

Definition at line 1160 of file aiks_dl_basic_unittests.cc.

1160  {
1161  DisplayListBuilder builder;
1162 
1163  DlPaint red;
1164  red.setColor(DlColor::kRed());
1165  builder.Skew(2, 5);
1166  builder.DrawRect(SkRect::MakeXYWH(0, 0, 100, 100), red);
1167 
1168  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1169 }

◆ TEST_P() [26/454]

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

Definition at line 928 of file aiks_dl_unittests.cc.

928  {
929  DisplayListBuilder recorder_canvas;
930  DlPaint paint;
931  paint.setColor(DlColor::RGBA(0.9568, 0.2627, 0.2118, 1.0));
932  recorder_canvas.DrawRect(SkRect::MakeXYWH(100.0, 100.0, 600, 600), paint);
933  paint.setColor(DlColor::RGBA(0.1294, 0.5882, 0.9529, 1.0));
934  recorder_canvas.DrawRect(SkRect::MakeXYWH(200.0, 200.0, 600, 600), paint);
935 
936  DisplayListBuilder canvas;
937  AiksContext renderer(GetContext(), nullptr);
938  paint.setColor(DlColor::kTransparent());
939  canvas.DrawPaint(paint);
940 
941  auto image =
942  DisplayListToTexture(recorder_canvas.Build(), {1000, 1000}, renderer);
943  if (image) {
944  canvas.DrawImage(DlImageImpeller::Make(image), {}, {});
945  paint.setColor(DlColor::RGBA(0.1, 0.1, 0.1, 0.2));
946  canvas.DrawRect(SkRect::MakeSize({1000, 1000}), paint);
947  }
948 
949  ASSERT_TRUE(OpenPlaygroundHere(canvas.Build()));
950 }

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

◆ TEST_P() [27/454]

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(DlBlendColorFilter::Make(
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() [28/454]

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({100, 100}, 50, paint);
248 
249  paint.setColor(DlColor::kGreenYellow());
250  builder.DrawCircle({300, 200}, 100, paint);
251 
252  paint.setColor(DlColor::kDarkMagenta());
253  builder.DrawCircle({140, 170}, 75, paint);
254 
255  paint.setColor(DlColor::kOrangeRed());
256  builder.DrawCircle({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 = DlBlurImageFilter::Make(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() [29/454]

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

Definition at line 271 of file aiks_dl_blur_unittests.cc.

271  {
272  DisplayListBuilder builder;
273 
274  DlPaint paint;
275  paint.setColor(DlColor::kGreen());
276  builder.DrawCircle({400, 400}, 300, paint);
277 
278  DlPaint save_paint;
279  save_paint.setBlendMode(DlBlendMode::kSrc);
280 
281  auto backdrop_filter =
282  DlBlurImageFilter::Make(999999, 999999, DlTileMode::kClamp);
283  builder.SaveLayer(nullptr, &save_paint, backdrop_filter.get());
284  builder.Restore();
285 
286  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
287 }

◆ TEST_P() [30/454]

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({100, 100}, 50, paint);
215 
216  paint.setColor(DlColor::kGreenYellow());
217  builder.DrawCircle({300, 200}, 100, paint);
218 
219  paint.setColor(DlColor::kDarkMagenta());
220  builder.DrawCircle({140, 170}, 75, paint);
221 
222  paint.setColor(DlColor::kOrangeRed());
223  builder.DrawCircle({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 = DlBlurImageFilter::Make(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 }

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

◆ TEST_P() [31/454]

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

Definition at line 786 of file aiks_dl_basic_unittests.cc.

786  {
787  DisplayListBuilder builder;
788 
789  builder.Scale(GetContentScale().x, GetContentScale().y);
790 
791  // Draw something interesting in the background.
792  std::vector<DlColor> colors = {DlColor::RGBA(0.9568, 0.2627, 0.2118, 1.0),
793  DlColor::RGBA(0.1294, 0.5882, 0.9529, 1.0)};
794  std::vector<Scalar> stops = {
795  0.0,
796  1.0,
797  };
798  DlPaint paint;
799  paint.setColorSource(DlColorSource::MakeLinear(
800  /*start_point=*/{0, 0}, //
801  /*end_point=*/{100, 100}, //
802  /*stop_count=*/2, //
803  /*colors=*/colors.data(), //
804  /*stops=*/stops.data(), //
805  /*tile_mode=*/DlTileMode::kRepeat //
806  ));
807 
808  builder.DrawPaint(paint);
809 
810  SkRect clip_rect = SkRect::MakeLTRB(50, 50, 400, 300);
811  SkRRect clip_rrect = SkRRect::MakeRectXY(clip_rect, 100, 100);
812 
813  // Draw a clipped SaveLayer, where the clip coverage and SaveLayer size are
814  // the same.
815  builder.ClipRRect(clip_rrect, DlCanvas::ClipOp::kIntersect);
816 
817  DlPaint save_paint;
818  auto backdrop_filter = std::make_shared<DlColorFilterImageFilter>(
819  DlBlendColorFilter::Make(DlColor::kRed(), DlBlendMode::kExclusion));
820  builder.SaveLayer(&clip_rect, &save_paint, backdrop_filter.get());
821 
822  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
823 }

◆ TEST_P() [32/454]

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

Definition at line 289 of file aiks_dl_blur_unittests.cc.

289  {
290  DisplayListBuilder builder;
291  builder.ClipRect(SkRect::MakeXYWH(100, 150, 400, 400));
292 
293  DlPaint paint;
294  paint.setColor(DlColor::kGreen());
295  paint.setImageFilter(DlBlurImageFilter::Make(20, 20, DlTileMode::kDecal));
296  builder.DrawCircle({400, 400}, 200, paint);
297  builder.Restore();
298 
299  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
300 }

◆ TEST_P() [33/454]

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

Definition at line 1407 of file aiks_dl_basic_unittests.cc.

1407  {
1408  DisplayListBuilder builder;
1409 
1410  DlPaint paint;
1411  paint.setColor(DlColor::kWhite());
1412  builder.DrawPaint(paint);
1413 
1414  // Draw a green circle on the screen.
1415  {
1416  // Increase the clip depth for the savelayer to contend with.
1417  SkPath path = SkPath::Circle(100, 100, 50);
1418  builder.ClipPath(path);
1419 
1420  SkRect bounds = SkRect::MakeXYWH(50, 50, 100, 100);
1421  DlPaint save_paint;
1422  builder.SaveLayer(&bounds, &save_paint);
1423 
1424  // Fill the layer with white.
1425  paint.setColor(DlColor::kWhite());
1426  builder.DrawRect(SkRect::MakeSize(SkSize{400, 400}), paint);
1427  // Fill the layer with green, but do so with a color blend that can't be
1428  // collapsed into the parent pass.
1429  paint.setColor(DlColor::kGreen());
1430  paint.setBlendMode(DlBlendMode::kHardLight);
1431  builder.DrawRect(SkRect::MakeSize(SkSize{400, 400}), paint);
1432  }
1433 
1434  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1435 }

◆ TEST_P() [34/454]

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

Definition at line 41 of file aiks_dl_runtime_effect_unittests.cc.

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

◆ TEST_P() [35/454]

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

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

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  DlBlendColorFilter::Make(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() [38/454]

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  DlBlendColorFilter::Make(DlColor::kYellow(), DlBlendMode::kSrcOver));
88  paint.setInvertColors(true);
89 
90  builder.DrawPaint(paint);
91  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
92 }

◆ TEST_P() [39/454]

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

Definition at line 550 of file aiks_dl_gradient_unittests.cc.

550  {
551  Scalar size = 256;
552  DisplayListBuilder builder;
553  DlPaint paint;
554  paint.setColor(DlColor::kWhite());
555  builder.DrawRect(SkRect::MakeXYWH(0, 0, size * 3, size * 3), paint);
556  std::vector<DlColor> colors = {
557  DlColor(Color::MakeRGBA8(0xF4, 0x43, 0x36, 0xFF).ToARGB()),
558  DlColor(Color::MakeRGBA8(0xFF, 0xEB, 0x3B, 0xFF).ToARGB()),
559  DlColor(Color::MakeRGBA8(0x4c, 0xAF, 0x50, 0xFF).ToARGB()),
560  DlColor(Color::MakeRGBA8(0x21, 0x96, 0xF3, 0xFF).ToARGB())};
561  std::vector<Scalar> stops = {0.0, 1.f / 3.f, 2.f / 3.f, 1.0};
562  std::array<std::tuple<SkPoint, float, SkPoint, float>, 8> array{
563  std::make_tuple(SkPoint::Make(size / 2.f, size / 2.f), 0.f,
564  SkPoint::Make(size / 2.f, size / 2.f), size / 2.f),
565  std::make_tuple(SkPoint::Make(size / 2.f, size / 2.f), size / 4.f,
566  SkPoint::Make(size / 2.f, size / 2.f), size / 2.f),
567  std::make_tuple(SkPoint::Make(size / 4.f, size / 4.f), 0.f,
568  SkPoint::Make(size / 2.f, size / 2.f), size / 2.f),
569  std::make_tuple(SkPoint::Make(size / 4.f, size / 4.f), size / 2.f,
570  SkPoint::Make(size / 2.f, size / 2.f), 0),
571  std::make_tuple(SkPoint::Make(size / 4.f, size / 4.f), size / 4.f,
572  SkPoint::Make(size / 2.f, size / 2.f), size / 2.f),
573  std::make_tuple(SkPoint::Make(size / 4.f, size / 4.f), size / 16.f,
574  SkPoint::Make(size / 2.f, size / 2.f), size / 8.f),
575  std::make_tuple(SkPoint::Make(size / 4.f, size / 4.f), size / 8.f,
576  SkPoint::Make(size / 2.f, size / 2.f), size / 16.f),
577  std::make_tuple(SkPoint::Make(size / 8.f, size / 8.f), size / 8.f,
578  SkPoint::Make(size / 2.f, size / 2.f), size / 8.f),
579  };
580  for (int i = 0; i < 8; i++) {
581  builder.Save();
582  builder.Translate((i % 3) * size, i / 3 * size);
583  paint.setColorSource(DlColorSource::MakeConical(
584  std::get<2>(array[i]), std::get<3>(array[i]), std::get<0>(array[i]),
585  std::get<1>(array[i]), stops.size(), colors.data(), stops.data(),
586  DlTileMode::kClamp));
587  builder.DrawRect(SkRect::MakeXYWH(0, 0, size, size), paint);
588  builder.Restore();
589  }
590  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
591 }

◆ TEST_P() [40/454]

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

Definition at line 186 of file aiks_dl_gradient_unittests.cc.

186  {
188 }

References CanRenderConicalGradientWithDithering().

◆ TEST_P() [41/454]

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

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

Definition at line 374 of file aiks_dl_unittests.cc.

374  {
375  DisplayListBuilder builder(GetCullRect(GetWindowSize()));
376 
377  DlPaint paint;
378  paint.setColor(DlColor::kRed());
379  builder.DrawPaint(paint);
380  // Draw an empty savelayer with a destructive blend mode, which will replace
381  // the entire red screen with fully transparent black, except for the green
382  // circle drawn within the layer.
383 
384  DlPaint save_paint;
385  save_paint.setBlendMode(DlBlendMode::kSrc);
386  builder.SaveLayer(nullptr, &save_paint);
387 
388  DlPaint draw_paint;
389  draw_paint.setColor(DlColor::kGreen());
390  builder.DrawCircle({300, 300}, 100, draw_paint);
391  builder.Restore();
392 
393  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
394 }

◆ TEST_P() [43/454]

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

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")), {10, 10},
172  {});
173  builder.DrawPath(path, paint);
174 
175  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
176 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [45/454]

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

Definition at line 339 of file aiks_dl_basic_unittests.cc.

339  {
340  DisplayListBuilder builder;
341  DlPaint paint;
342 
343  DlColor colors[2] = {
344  DlColor::RGBA(0.9568, 0.2627, 0.2118, 1.0),
345  DlColor::RGBA(0.1294, 0.5882, 0.9529, 1.0),
346  };
347  DlScalar stops[2] = {
348  0.0,
349  1.0,
350  };
351 
352  paint.setColorSource(DlColorSource::MakeLinear(
353  /*start_point=*/{0, 0}, //
354  /*end_point=*/{100, 100}, //
355  /*stop_count=*/2, //
356  /*colors=*/colors, //
357  /*stops=*/stops, //
358  /*tile_mode=*/DlTileMode::kRepeat //
359  ));
360 
361  builder.Save();
362  builder.Translate(100, 100);
363  builder.DrawRect(SkRect::MakeXYWH(0, 0, 200, 200), paint);
364  builder.Restore();
365 
366  builder.Save();
367  builder.Translate(100, 400);
368  builder.DrawCircle({100, 100}, 100, paint);
369  builder.Restore();
370  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
371 }

◆ TEST_P() [46/454]

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

Definition at line 288 of file aiks_dl_text_unittests.cc.

288  {
289  DisplayListBuilder builder;
290 
291  DlPaint paint;
292  paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
293  builder.DrawPaint(paint);
294 
295  ASSERT_TRUE(RenderTextInCanvasSkia(
296  GetContext(), builder, "😀 😃 😄 😁 😆 😅 😂 🤣 🥲 😊", kFontFixture));
297  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
298 }

References kFontFixture, and RenderTextInCanvasSkia().

◆ TEST_P() [47/454]

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

Definition at line 316 of file aiks_dl_text_unittests.cc.

316  {
317  DisplayListBuilder builder;
318 
319  DlPaint paint;
320  paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
321  builder.DrawPaint(paint);
322 
323  ASSERT_TRUE(RenderTextInCanvasSkia(
324  GetContext(), builder, "😀 😃 😄 😁 😆 😅 😂 🤣 🥲 😊", kFontFixture,
325  {.color = DlColor::kBlack().modulateOpacity(0.5)}));
326  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
327 }

References kFontFixture, and RenderTextInCanvasSkia().

◆ TEST_P() [48/454]

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

Definition at line 300 of file aiks_dl_text_unittests.cc.

300  {
301  DisplayListBuilder builder;
302 
303  builder.Scale(GetContentScale().x, GetContentScale().y);
304  DlPaint paint;
305  paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
306  builder.DrawPaint(paint);
307 
308  ASSERT_TRUE(RenderTextInCanvasSkia(
309  GetContext(), builder, "😀 😃 😄 😁 😆 😅 😂 🤣 🥲 😊", kFontFixture,
310  TextRenderOptions{
311  .color = DlColor::kBlue(),
312  .filter = DlBlurMaskFilter::Make(DlBlurStyle::kNormal, 4)}));
313  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
314 }

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

◆ TEST_P() [49/454]

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  DlBlendColorFilter::Make(DlColor::kGreen(), DlBlendMode::kColor));
199  builder.DrawCircle({400, 400}, 200, paint);
200  builder.Restore();
201 
202  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
203 }

References impeller::Sigma::sigma.

◆ TEST_P() [50/454]

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  DlBlendColorFilter::Make(DlColor::kGreen(), DlBlendMode::kSrc));
179  builder.DrawCircle({400, 400}, 200, paint);
180 
181  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
182 }

References impeller::Sigma::sigma.

◆ TEST_P() [51/454]

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

Definition at line 593 of file aiks_dl_gradient_unittests.cc.

593  {
594  std::vector<DlColor> colors = {
595  DlColor(Color::MakeRGBA8(0xF4, 0x43, 0x36, 0xFF).ToARGB()),
596  DlColor(Color::MakeRGBA8(0xFF, 0xEB, 0x3B, 0xFF).ToARGB()),
597  DlColor(Color::MakeRGBA8(0x4c, 0xAF, 0x50, 0xFF).ToARGB()),
598  DlColor(Color::MakeRGBA8(0x21, 0x96, 0xF3, 0xFF).ToARGB())};
599  std::vector<Scalar> stops = {0.0, 1.f / 3.f, 2.f / 3.f, 1.0};
600 
601  std::array<std::shared_ptr<DlColorSource>, 3> color_sources = {
602  DlColorSource::MakeLinear({0, 0}, {100, 100}, stops.size(), colors.data(),
603  stops.data(), DlTileMode::kDecal),
604  DlColorSource::MakeRadial({100, 100}, 100, stops.size(), colors.data(),
605  stops.data(), DlTileMode::kDecal),
606  DlColorSource::MakeSweep({100, 100}, 45, 135, stops.size(), colors.data(),
607  stops.data(), DlTileMode::kDecal),
608  };
609 
610  DisplayListBuilder builder;
611  DlPaint paint;
612  paint.setColor(DlColor::kWhite());
613  builder.DrawRect(SkRect::MakeLTRB(0, 0, 605, 205), paint);
614  for (int i = 0; i < 3; i++) {
615  builder.Save();
616  builder.Translate(i * 200.0f, 0);
617  paint.setColorSource(color_sources[i]);
618  builder.DrawRect(SkRect::MakeLTRB(0, 0, 200, 200), paint);
619  builder.Restore();
620  }
621  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
622 }

◆ TEST_P() [52/454]

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

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

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

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

Definition at line 218 of file aiks_dl_basic_unittests.cc.

218  {
219  DisplayListBuilder builder;
220  auto image = DlImageImpeller::Make(CreateTextureForFixture("kalimba.jpg"));
221 
222  SkSize image_half_size = SkSize::Make(image->dimensions().fWidth * 0.5f,
223  image->dimensions().fHeight * 0.5f);
224 
225  // Render the bottom right quarter of the source image in a stretched rect.
226  auto source_rect = SkRect::MakeSize(image_half_size);
227  source_rect =
228  source_rect.makeOffset(image_half_size.fWidth, image_half_size.fHeight);
229 
230  builder.DrawImageRect(image, source_rect,
231  SkRect::MakeXYWH(100, 100, 600, 600),
232  DlImageSampling::kNearestNeighbor);
233  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
234 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [56/454]

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  DlBlendColorFilter::Make(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() [57/454]

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

Definition at line 268 of file aiks_dl_text_unittests.cc.

268  {
269  DisplayListBuilder builder;
270 
271  DlPaint paint;
272  paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
273  builder.DrawPaint(paint);
274 
275  ASSERT_TRUE(RenderTextInCanvasSkia(
276  GetContext(), builder, "the quick brown fox jumped over the lazy dog!.?",
277  "HomemadeApple.ttf"));
278  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
279 }

References RenderTextInCanvasSkia().

◆ TEST_P() [58/454]

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

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

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

Definition at line 80 of file aiks_dl_gradient_unittests.cc.

80  {
81  DisplayListBuilder builder;
82  Point scale = GetContentScale();
83  builder.Scale(scale.x, scale.y);
84  DlPaint paint;
85  builder.Translate(100.0f, 0);
86 
87  std::vector<DlColor> colors = {
88  DlColor(Color{0.9568, 0.2627, 0.2118, 1.0}.ToARGB()),
89  DlColor(Color{0.1294, 0.5882, 0.9529, 0.0}.ToARGB())};
90  std::vector<Scalar> stops = {0.0, 1.0};
91 
92  paint.setColorSource(DlColorSource::MakeLinear(
93  {0, 0}, {200, 200}, 2, colors.data(), stops.data(), DlTileMode::kDecal));
94  // Overlay the gradient with 25% green. This should appear as the entire
95  // rectangle being drawn with 25% green, including the border area outside the
96  // decal gradient.
97  paint.setColorFilter(DlBlendColorFilter::Make(DlColor::kGreen().withAlpha(64),
98  DlBlendMode::kSrcOver));
99  paint.setColor(DlColor::kWhite());
100  builder.DrawRect(SkRect::MakeXYWH(0, 0, 600, 600), paint);
101  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
102 }

References scale, and impeller::Color::ToARGB().

◆ TEST_P() [61/454]

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

Definition at line 256 of file aiks_dl_gradient_unittests.cc.

256  {
257  CanRenderLinearGradientManyColors(this, DlTileMode::kClamp);
258 }

◆ TEST_P() [62/454]

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

Definition at line 265 of file aiks_dl_gradient_unittests.cc.

265  {
266  CanRenderLinearGradientManyColors(this, DlTileMode::kDecal);
267 }

◆ TEST_P() [63/454]

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

Definition at line 262 of file aiks_dl_gradient_unittests.cc.

262  {
263  CanRenderLinearGradientManyColors(this, DlTileMode::kMirror);
264 }

◆ TEST_P() [64/454]

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

Definition at line 259 of file aiks_dl_gradient_unittests.cc.

259  {
260  CanRenderLinearGradientManyColors(this, DlTileMode::kRepeat);
261 }

◆ TEST_P() [65/454]

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

Definition at line 300 of file aiks_dl_gradient_unittests.cc.

300  {
301  auto callback = [&]() -> sk_sp<DisplayList> {
302  const char* tile_mode_names[] = {"Clamp", "Repeat", "Mirror", "Decal"};
303  const DlTileMode tile_modes[] = {DlTileMode::kClamp, DlTileMode::kRepeat,
304  DlTileMode::kMirror, DlTileMode::kDecal};
305 
306  static int selected_tile_mode = 0;
307  static Matrix matrix;
308  if (AiksTest::ImGuiBegin("Controls", nullptr,
309  ImGuiWindowFlags_AlwaysAutoResize)) {
310  ImGui::Combo("Tile mode", &selected_tile_mode, tile_mode_names,
311  sizeof(tile_mode_names) / sizeof(char*));
312  std::string label = "##1";
313  for (int i = 0; i < 4; i++) {
314  ImGui::InputScalarN(label.c_str(), ImGuiDataType_Float,
315  &(matrix.vec[i]), 4, NULL, NULL, "%.2f", 0);
316  label[2]++;
317  }
318  ImGui::End();
319  }
320 
321  DisplayListBuilder builder;
322  DlPaint paint;
323  builder.Translate(100.0, 100.0);
324  auto tile_mode = tile_modes[selected_tile_mode];
325 
326  std::vector<DlColor> colors = {
327  DlColor(Color{0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0}.ToARGB()),
328  DlColor(Color{0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0}.ToARGB()),
329  DlColor(Color{0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0}.ToARGB()),
330  DlColor(Color{0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0}.ToARGB()),
331  DlColor(Color{0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0}.ToARGB()),
332  DlColor(Color{0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0}.ToARGB()),
333  DlColor(Color{0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0}.ToARGB())};
334  std::vector<Scalar> stops = {
335  0.0, 2.0 / 62.0, 4.0 / 62.0, 8.0 / 62.0, 16.0 / 62.0, 32.0 / 62.0, 1.0,
336  };
337 
338  paint.setColorSource(DlColorSource::MakeLinear({0, 0}, {200, 200},
339  stops.size(), colors.data(),
340  stops.data(), tile_mode));
341 
342  builder.DrawRect(SkRect::MakeXYWH(0, 0, 600, 600), paint);
343  return builder.Build();
344  };
345  ASSERT_TRUE(OpenPlaygroundHere(callback));
346 }

References impeller::Color::ToARGB(), and impeller::Matrix::vec.

◆ TEST_P() [66/454]

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

Definition at line 348 of file aiks_dl_gradient_unittests.cc.

348  {
349  DisplayListBuilder builder;
350 
351  std::vector<DlColor> colors = {
352  DlColor::kRed(), DlColor::kWhite(), DlColor::kRed(), DlColor::kWhite(),
353  DlColor::kRed(), DlColor::kWhite(), DlColor::kRed(), DlColor::kWhite(),
354  DlColor::kRed(), DlColor::kWhite(), DlColor::kRed()};
355  std::vector<Scalar> stops = {0.0, 0.1, 0.2, 0.3, 0.4, 0.5,
356  0.6, 0.7, 0.8, 0.9, 1.0};
357 
358  DlPaint paint;
359  paint.setColor(DlColor::kWhite());
360  paint.setColorSource(DlColorSource::MakeLinear(
361  {200, 200}, {400, 400}, stops.size(), colors.data(), stops.data(),
362  DlTileMode::kClamp));
363  paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kNormal, 20));
364 
365  builder.DrawCircle({300, 300}, 200, paint);
366  builder.DrawRect(SkRect::MakeLTRB(100, 300, 500, 600), paint);
367 
368  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
369 }

◆ TEST_P() [67/454]

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

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

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

Definition at line 296 of file aiks_dl_gradient_unittests.cc.

296  {
297  CanRenderLinearGradientWayManyColors(this, DlTileMode::kClamp);
298 }

◆ TEST_P() [70/454]

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

Definition at line 120 of file aiks_dl_gradient_unittests.cc.

120  {
122 }

References CanRenderLinearGradientWithDithering().

◆ TEST_P() [71/454]

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

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({400, 400}, 300, paint);
160  builder.Restore();
161 
162  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
163 }

◆ TEST_P() [73/454]

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

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

Definition at line 464 of file aiks_dl_path_unittests.cc.

464  {
465  DisplayListBuilder builder;
466 
467  DlPaint paint;
468  paint.setColor(DlColor::kRed());
469 
470  SkPoint radii[4] = {{50, 50}, {50, 50}, {50, 50}, {50, 50}};
471 
472  const Scalar kTriangleHeight = 100;
473  SkRRect rrect;
474  rrect.setRectRadii(
475  SkRect::MakeXYWH(-kTriangleHeight / 2.0f, -kTriangleHeight / 2.0f,
476  kTriangleHeight, kTriangleHeight),
477  radii //
478  );
479 
480  builder.Translate(200, 200);
481  // Form a path similar to the Material drop slider value indicator. Both
482  // shapes should render identically side-by-side.
483  {
484  SkPath path;
485  path.moveTo(0, kTriangleHeight);
486  path.lineTo(-kTriangleHeight / 2.0f, 0);
487  path.lineTo(kTriangleHeight / 2.0f, 0);
488  path.close();
489  path.addRRect(rrect);
490 
491  builder.DrawPath(path, paint);
492  }
493  builder.Translate(100, 0);
494 
495  {
496  SkPath path;
497  path.moveTo(0, kTriangleHeight);
498  path.lineTo(-kTriangleHeight / 2.0f, 0);
499  path.lineTo(0, -10);
500  path.lineTo(kTriangleHeight / 2.0f, 0);
501  path.close();
502  path.addRRect(rrect);
503 
504  builder.DrawPath(path, paint);
505  }
506 
507  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
508 }

◆ TEST_P() [75/454]

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

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

Definition at line 371 of file aiks_dl_gradient_unittests.cc.

371  {
372  auto callback = [&]() -> sk_sp<DisplayList> {
373  const char* tile_mode_names[] = {"Clamp", "Repeat", "Mirror", "Decal"};
374  const DlTileMode tile_modes[] = {DlTileMode::kClamp, DlTileMode::kRepeat,
375  DlTileMode::kMirror, DlTileMode::kDecal};
376 
377  static int selected_tile_mode = 0;
378  static Matrix matrix;
379  if (AiksTest::ImGuiBegin("Controls", nullptr,
380  ImGuiWindowFlags_AlwaysAutoResize)) {
381  ImGui::Combo("Tile mode", &selected_tile_mode, tile_mode_names,
382  sizeof(tile_mode_names) / sizeof(char*));
383  std::string label = "##1";
384  for (int i = 0; i < 4; i++) {
385  ImGui::InputScalarN(label.c_str(), ImGuiDataType_Float,
386  &(matrix.vec[i]), 4, NULL, NULL, "%.2f", 0);
387  label[2]++;
388  }
389  ImGui::End();
390  }
391 
392  DisplayListBuilder builder;
393  DlPaint paint;
394  builder.Translate(100.0, 100.0);
395  auto tile_mode = tile_modes[selected_tile_mode];
396 
397  std::vector<DlColor> colors = {
398  DlColor(Color{0.9568, 0.2627, 0.2118, 1.0}.ToARGB()),
399  DlColor(Color{0.1294, 0.5882, 0.9529, 1.0}.ToARGB())};
400  std::vector<Scalar> stops = {0.0, 1.0};
401 
402  paint.setColorSource(DlColorSource::MakeRadial(
403  {100, 100}, 100, 2, colors.data(), stops.data(), tile_mode));
404 
405  builder.DrawRect(SkRect::MakeXYWH(0, 0, 600, 600), paint);
406  return builder.Build();
407  };
408  ASSERT_TRUE(OpenPlaygroundHere(callback));
409 }

References impeller::Color::ToARGB(), and impeller::Matrix::vec.

◆ TEST_P() [77/454]

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

Definition at line 411 of file aiks_dl_gradient_unittests.cc.

411  {
412  auto callback = [&]() -> sk_sp<DisplayList> {
413  const char* tile_mode_names[] = {"Clamp", "Repeat", "Mirror", "Decal"};
414  const DlTileMode tile_modes[] = {DlTileMode::kClamp, DlTileMode::kRepeat,
415  DlTileMode::kMirror, DlTileMode::kDecal};
416 
417  static int selected_tile_mode = 0;
418  static Matrix matrix = {
419  1, 0, 0, 0, //
420  0, 1, 0, 0, //
421  0, 0, 1, 0, //
422  0, 0, 0, 1 //
423  };
424  if (AiksTest::ImGuiBegin("Controls", nullptr,
425  ImGuiWindowFlags_AlwaysAutoResize)) {
426  ImGui::Combo("Tile mode", &selected_tile_mode, tile_mode_names,
427  sizeof(tile_mode_names) / sizeof(char*));
428  std::string label = "##1";
429  for (int i = 0; i < 4; i++) {
430  ImGui::InputScalarN(label.c_str(), ImGuiDataType_Float,
431  &(matrix.vec[i]), 4, NULL, NULL, "%.2f", 0);
432  label[2]++;
433  }
434  ImGui::End();
435  }
436 
437  DisplayListBuilder builder;
438  DlPaint paint;
439  builder.Translate(100.0, 100.0);
440  auto tile_mode = tile_modes[selected_tile_mode];
441 
442  std::vector<DlColor> colors = {
443  DlColor(Color{0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0}.ToARGB()),
444  DlColor(Color{0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0}.ToARGB()),
445  DlColor(Color{0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0}.ToARGB()),
446  DlColor(Color{0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0}.ToARGB()),
447  DlColor(Color{0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0}.ToARGB()),
448  DlColor(Color{0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0}.ToARGB()),
449  DlColor(Color{0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0}.ToARGB())};
450  std::vector<Scalar> stops = {
451  0.0,
452  (1.0 / 6.0) * 1,
453  (1.0 / 6.0) * 2,
454  (1.0 / 6.0) * 3,
455  (1.0 / 6.0) * 4,
456  (1.0 / 6.0) * 5,
457  1.0,
458  };
459 
460  paint.setColorSource(DlColorSource::MakeRadial(
461  {100, 100}, 100, stops.size(), colors.data(), stops.data(), tile_mode));
462 
463  builder.DrawRect(SkRect::MakeXYWH(0, 0, 600, 600), paint);
464  return builder.Build();
465  };
466  ASSERT_TRUE(OpenPlaygroundHere(callback));
467 }

References impeller::Color::ToARGB(), and impeller::Matrix::vec.

◆ TEST_P() [78/454]

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

Definition at line 140 of file aiks_dl_gradient_unittests.cc.

140  {
142 }

References CanRenderRadialGradientWithDithering().

◆ TEST_P() [79/454]

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

Definition at line 373 of file aiks_dl_basic_unittests.cc.

373  {
374  DisplayListBuilder builder;
375  DlPaint paint;
376  paint.setColor(DlColor::kRed());
377 
378  SkRRect rrect;
379  SkVector radii[4] = {
380  SkVector{50, 25},
381  SkVector{25, 50},
382  SkVector{50, 25},
383  SkVector{25, 50},
384  };
385  rrect.setRectRadii(SkRect::MakeXYWH(100, 100, 500, 500), radii);
386 
387  builder.DrawRRect(rrect, paint);
388 
389  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
390 }

◆ TEST_P() [80/454]

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

Definition at line 236 of file aiks_dl_basic_unittests.cc.

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

References impeller::DlImageImpeller::Make().

◆ TEST_P() [81/454]

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

Definition at line 147 of file aiks_dl_text_unittests.cc.

147  {
148  DisplayListBuilder builder;
149 
150  DlPaint paint;
151  paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
152  builder.DrawPaint(paint);
153 
154  ASSERT_TRUE(RenderTextInCanvasSkia(
155  GetContext(), builder, "the quick brown fox jumped over the lazy dog!.?",
156  "Roboto-Regular.ttf",
157  {
158  .stroke = true,
159  }));
160  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
161 }

References RenderTextInCanvasSkia().

◆ TEST_P() [82/454]

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

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

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

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

Definition at line 490 of file aiks_dl_gradient_unittests.cc.

490  {
491  CanRenderSweepGradient(this, DlTileMode::kClamp);
492 }

◆ TEST_P() [86/454]

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

Definition at line 499 of file aiks_dl_gradient_unittests.cc.

499  {
500  CanRenderSweepGradient(this, DlTileMode::kDecal);
501 }

◆ TEST_P() [87/454]

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

Definition at line 537 of file aiks_dl_gradient_unittests.cc.

537  {
538  CanRenderSweepGradientManyColors(this, DlTileMode::kClamp);
539 }

◆ TEST_P() [88/454]

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

Definition at line 546 of file aiks_dl_gradient_unittests.cc.

546  {
547  CanRenderSweepGradientManyColors(this, DlTileMode::kDecal);
548 }

◆ TEST_P() [89/454]

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

Definition at line 543 of file aiks_dl_gradient_unittests.cc.

543  {
544  CanRenderSweepGradientManyColors(this, DlTileMode::kMirror);
545 }

◆ TEST_P() [90/454]

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

Definition at line 540 of file aiks_dl_gradient_unittests.cc.

540  {
541  CanRenderSweepGradientManyColors(this, DlTileMode::kRepeat);
542 }

◆ TEST_P() [91/454]

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

Definition at line 496 of file aiks_dl_gradient_unittests.cc.

496  {
497  CanRenderSweepGradient(this, DlTileMode::kMirror);
498 }

◆ TEST_P() [92/454]

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

Definition at line 493 of file aiks_dl_gradient_unittests.cc.

493  {
494  CanRenderSweepGradient(this, DlTileMode::kRepeat);
495 }

◆ TEST_P() [93/454]

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

Definition at line 163 of file aiks_dl_gradient_unittests.cc.

163  {
165 }

References CanRenderSweepGradientWithDithering().

◆ TEST_P() [94/454]

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

Definition at line 118 of file aiks_dl_text_unittests.cc.

118  {
119  DisplayListBuilder builder;
120 
121  DlPaint paint;
122  paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
123  builder.DrawPaint(paint);
124  ASSERT_TRUE(RenderTextInCanvasSkia(
125  GetContext(), builder, "the quick brown fox jumped over the lazy dog!.?",
126  "Roboto-Regular.ttf"));
127 
128  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
129 }

References RenderTextInCanvasSkia().

◆ TEST_P() [95/454]

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

Definition at line 207 of file aiks_dl_text_unittests.cc.

207  {
208  DisplayListBuilder builder;
209 
210  DlPaint paint;
211  paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
212  builder.DrawPaint(paint);
213 
214  ASSERT_TRUE(RenderTextInCanvasSTB(
215  GetContext(), builder, "the quick brown fox jumped over the lazy dog!.?",
216  "Roboto-Regular.ttf"));
217 
218  SetTypographerContext(TypographerContextSTB::Make());
219  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
220 }

References RenderTextInCanvasSTB().

◆ TEST_P() [96/454]

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

Definition at line 193 of file aiks_dl_text_unittests.cc.

193  {
194  DisplayListBuilder builder;
195 
196  DlPaint paint;
197  paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
198  builder.DrawPaint(paint);
199  builder.Scale(2.625, 2.625);
200 
201  ASSERT_TRUE(RenderTextInCanvasSkia(
202  GetContext(), builder, "the quick brown fox jumped over the lazy dog!.?",
203  "Roboto-Regular.ttf"));
204  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
205 }

References RenderTextInCanvasSkia().

◆ TEST_P() [97/454]

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

Definition at line 179 of file aiks_dl_text_unittests.cc.

179  {
180  DisplayListBuilder builder;
181 
182  DlPaint paint;
183  paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
184  builder.DrawPaint(paint);
185  builder.Scale(0.5, 0.5);
186 
187  ASSERT_TRUE(RenderTextInCanvasSkia(
188  GetContext(), builder, "the quick brown fox jumped over the lazy dog!.?",
189  "Roboto-Regular.ttf"));
190  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
191 }

References RenderTextInCanvasSkia().

◆ TEST_P() [98/454]

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

Definition at line 131 of file aiks_dl_text_unittests.cc.

131  {
132  DisplayListBuilder builder;
133 
134  DlPaint paint;
135  paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
136  builder.DrawPaint(paint);
137  builder.Translate(1000, 0);
138  builder.Scale(-1, 1);
139 
140  ASSERT_TRUE(RenderTextInCanvasSkia(
141  GetContext(), builder, "the quick brown fox jumped over the lazy dog!.?",
142  "Roboto-Regular.ttf"));
143 
144  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
145 }

References RenderTextInCanvasSkia().

◆ TEST_P() [99/454]

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

Definition at line 329 of file aiks_dl_text_unittests.cc.

329  {
330  DisplayListBuilder builder;
331 
332  DlPaint paint;
333  paint.setColor(DlColor::ARGB(0.1, 0.1, 0.1, 0.1));
334  builder.DrawPaint(paint);
335 
336  builder.Translate(100, 100);
337  builder.Scale(0.5, 0.5);
338 
339  // Blend the layer with the parent pass using kClear to expose the coverage.
340  paint.setBlendMode(DlBlendMode::kClear);
341  builder.SaveLayer(nullptr, &paint);
342  ASSERT_TRUE(RenderTextInCanvasSkia(
343  GetContext(), builder, "the quick brown fox jumped over the lazy dog!.?",
344  "Roboto-Regular.ttf"));
345  builder.Restore();
346 
347  // Render the text again over the cleared coverage rect.
348  ASSERT_TRUE(RenderTextInCanvasSkia(
349  GetContext(), builder, "the quick brown fox jumped over the lazy dog!.?",
350  "Roboto-Regular.ttf"));
351 
352  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
353 }

References RenderTextInCanvasSkia().

◆ TEST_P() [100/454]

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

Definition at line 355 of file aiks_dl_text_unittests.cc.

355  {
356  DisplayListBuilder builder;
357  builder.Translate(200, 150);
358 
359  // Construct the text blob.
360  auto mapping = flutter::testing::OpenFixtureAsSkData("wtf.otf");
361  ASSERT_NE(mapping, nullptr);
362 
363  Scalar font_size = 80;
364  sk_sp<SkFontMgr> font_mgr = txt::GetDefaultFontManager();
365  SkFont sk_font(font_mgr->makeFromData(mapping), font_size);
366 
367  DlPaint text_paint;
368  text_paint.setColor(DlColor::kBlue().withAlpha(255 * 0.8));
369 
370  struct {
371  SkPoint position;
372  const char* text;
373  } text[] = {{SkPoint::Make(0, 0), "0F0F0F0"},
374  {SkPoint::Make(1, 2), "789"},
375  {SkPoint::Make(1, 3), "456"},
376  {SkPoint::Make(1, 4), "123"},
377  {SkPoint::Make(0, 6), "0F0F0F0"}};
378  for (auto& t : text) {
379  builder.Save();
380  builder.Translate(t.position.x() * font_size * 2,
381  t.position.y() * font_size * 1.1);
382  {
383  auto blob = SkTextBlob::MakeFromString(t.text, sk_font);
384  ASSERT_NE(blob, nullptr);
385  auto frame = MakeTextFrameFromTextBlobSkia(blob);
386  builder.DrawTextFrame(frame, 0, 0, text_paint);
387  }
388  builder.Restore();
389  }
390 
391  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
392 }

References font_size, and impeller::MakeTextFrameFromTextBlobSkia().

◆ TEST_P() [101/454]

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

Definition at line 163 of file aiks_dl_text_unittests.cc.

163  {
164  DisplayListBuilder builder;
165 
166  DlPaint paint;
167  paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1));
168  builder.DrawPaint(paint);
169 
170  ASSERT_TRUE(RenderTextInCanvasSkia(GetContext(), builder, "LMNOP VWXYZ",
171  "Roboto-Medium.ttf",
172  {
173  .stroke = true,
174  .stroke_width = 4,
175  }));
176  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
177 }

References RenderTextInCanvasSkia().

◆ TEST_P() [102/454]

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

Definition at line 453 of file aiks_dl_text_unittests.cc.

453  {
454  // Verifies that text scales are clamped to work around
455  // https://github.com/flutter/flutter/issues/136112 .
456 
457  DisplayListBuilder builder;
458 
459  DlPaint save_paint;
460  builder.SaveLayer(nullptr, &save_paint);
461  builder.Transform(SkM44::ColMajor(Matrix(2000, 0, 0, 0, //
462  0, 2000, 0, 0, //
463  0, 0, -1, 9000, //
464  0, 0, -1, 7000 //
465  )
466  .m));
467 
468  ASSERT_TRUE(RenderTextInCanvasSkia(GetContext(), builder, "Hello world",
469  "Roboto-Regular.ttf"));
470  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
471 }

References RenderTextInCanvasSkia().

◆ TEST_P() [103/454]

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

Definition at line 473 of file aiks_dl_text_unittests.cc.

473  {
474  DisplayListBuilder text_builder;
475  ASSERT_TRUE(RenderTextInCanvasSkia(GetContext(), text_builder, "Hello world",
476  "Roboto-Regular.ttf"));
477  auto text_display_list = text_builder.Build();
478 
479  DisplayListBuilder builder;
480 
481  Matrix matrix = Matrix::MakeRow(2.0, 0.0, 0.0, 0.0, //
482  0.0, 2.0, 0.0, 0.0, //
483  0.0, 0.0, 1.0, 0.0, //
484  0.0, 0.002, 0.0, 1.0);
485 
486  DlPaint save_paint;
487  SkRect window_bounds =
488  SkRect::MakeXYWH(0, 0, GetWindowSize().width, GetWindowSize().height);
489  builder.SaveLayer(&window_bounds, &save_paint);
490  builder.Transform(SkM44::ColMajor(matrix.m));
491  builder.DrawDisplayList(text_display_list, 1.0f);
492  builder.Restore();
493 
494  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
495 }

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

◆ TEST_P() [104/454]

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

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

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

Definition at line 197 of file aiks_dl_basic_unittests.cc.

197  {
198  CanRenderTiledTexture(this, DlTileMode::kClamp);
199 }

◆ TEST_P() [107/454]

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

Definition at line 213 of file aiks_dl_basic_unittests.cc.

213  {
214  CanRenderTiledTexture(this, DlTileMode::kClamp,
215  Matrix::MakeTranslation({172.f, 172.f, 0.f}));
216 }

References impeller::Matrix::MakeTranslation().

◆ TEST_P() [108/454]

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

Definition at line 209 of file aiks_dl_basic_unittests.cc.

209  {
210  CanRenderTiledTexture(this, DlTileMode::kDecal);
211 }

◆ TEST_P() [109/454]

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

Definition at line 205 of file aiks_dl_basic_unittests.cc.

205  {
206  CanRenderTiledTexture(this, DlTileMode::kMirror);
207 }

◆ TEST_P() [110/454]

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

Definition at line 201 of file aiks_dl_basic_unittests.cc.

201  {
202  CanRenderTiledTexture(this, DlTileMode::kRepeat);
203 }

◆ TEST_P() [111/454]

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 349 of file aiks_dl_unittests.cc.

349  {
350  DisplayListBuilder builder(GetCullRect(GetWindowSize()));
351 
352  DlPaint paint;
353  paint.setColor(DlColor::kRed());
354  builder.DrawPaint(paint);
355 
356  // Draw two overlapping subpixel circles.
357  builder.SaveLayer({});
358 
359  DlPaint yellow_paint;
360  yellow_paint.setColor(DlColor::kYellow());
361  builder.DrawCircle({100, 100}, 0.1, yellow_paint);
362  builder.Restore();
363  builder.SaveLayer({});
364  builder.DrawCircle({100, 100}, 0.1, yellow_paint);
365  builder.Restore();
366 
367  DlPaint draw_paint;
368  draw_paint.setColor(DlColor::kGreen());
369  builder.DrawPaint(draw_paint);
370 
371  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
372 }

◆ TEST_P() [112/454]

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

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

Definition at line 321 of file aiks_dl_basic_unittests.cc.

321  {
322  DisplayListBuilder builder;
323 
324  DlPaint red;
325  red.setColor(DlColor::kRed());
326 
327  DlPaint alpha;
328  alpha.setColor(DlColor::kRed().modulateOpacity(0.5));
329 
330  builder.SaveLayer(nullptr, &alpha);
331 
332  builder.DrawCircle({125, 125}, 125, red);
333 
334  builder.Restore();
335 
336  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
337 }

◆ TEST_P() [114/454]

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

Definition at line 67 of file canvas_unittests.cc.

67  {
68  ContentContext context(GetContext(), nullptr);
69  auto canvas = CreateTestCanvas(context);
70 
71  ASSERT_EQ(canvas->GetSaveCount(), 1u);
72  ASSERT_EQ(canvas->Restore(), false);
73 
74  canvas->Translate(Size{100, 100});
75  canvas->Save(10);
76  ASSERT_EQ(canvas->GetSaveCount(), 2u);
77  ASSERT_MATRIX_NEAR(canvas->GetCurrentTransform(),
78  Matrix::MakeTranslation({100.0, 100.0, 0.0}));
79  ASSERT_TRUE(canvas->Restore());
80  ASSERT_EQ(canvas->GetSaveCount(), 1u);
81  ASSERT_MATRIX_NEAR(canvas->GetCurrentTransform(),
82  Matrix::MakeTranslation({100.0, 100.0, 0.0}));
83 }

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

◆ TEST_P() [115/454]

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

Definition at line 85 of file canvas_unittests.cc.

85  {
86  ContentContext context(GetContext(), nullptr);
87  auto canvas = CreateTestCanvas(context);
88 
89  Matrix identity;
90  ASSERT_MATRIX_NEAR(canvas->GetCurrentTransform(), identity);
91  canvas->Translate(Size{100, 100});
92  ASSERT_MATRIX_NEAR(canvas->GetCurrentTransform(),
93  Matrix::MakeTranslation({100.0, 100.0, 0.0}));
94 }

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

◆ TEST_P() [116/454]

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

Definition at line 486 of file aiks_dl_blend_unittests.cc.

486  {
487  DisplayListBuilder builder;
488 
489  DlPaint blue;
490  blue.setColor(DlColor::kBlue());
491  builder.DrawRect(SkRect::MakeXYWH(0, 0, 600.0, 600.0), blue);
492 
493  DlPaint clear;
494  clear.setBlendMode(DlBlendMode::kClear);
495 
496  builder.DrawCircle({300.0, 300.0}, 200.0, clear);
497 
498  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
499 }

◆ TEST_P() [117/454]

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

Definition at line 343 of file aiks_dl_blur_unittests.cc.

343  {
344  DisplayListBuilder builder;
345  DlPaint paint;
346  paint.setColor(DlColor::kBlue());
347  builder.DrawRect(SkRect::MakeXYWH(0, 0, 600.0, 600.0), paint);
348 
349  DlPaint clear;
350  clear.setBlendMode(DlBlendMode::kClear);
351  clear.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kNormal, 20));
352 
353  builder.DrawCircle({300.0, 300.0}, 200.0, clear);
354 
355  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
356 }

◆ TEST_P() [118/454]

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

Definition at line 1016 of file aiks_dl_basic_unittests.cc.

1016  {
1017  SetWindowSize({400, 400});
1018  DisplayListBuilder builder;
1019 
1020  builder.Scale(GetContentScale().x, GetContentScale().y);
1021 
1022  DlPaint paint;
1023  paint.setColor(DlColor::kRed());
1024  builder.DrawRect(SkRect::MakeLTRB(200, 200, 300, 300), paint);
1025 
1026  paint.setImageFilter(DlMatrixImageFilter::Make(SkMatrix::Scale(2, 2),
1027  DlImageSampling::kLinear));
1028  builder.SaveLayer(nullptr, &paint);
1029  // Draw a rectangle that would fully cover the parent pass size, but not
1030  // the subpass that it is rendered in.
1031  paint.setColor(DlColor::kGreen());
1032  builder.DrawRect(SkRect::MakeLTRB(0, 0, 400, 400), paint);
1033  // Draw a bigger rectangle to force the subpass to be bigger.
1034 
1035  paint.setColor(DlColor::kRed());
1036  builder.DrawRect(SkRect::MakeLTRB(0, 0, 800, 800), paint);
1037  builder.Restore();
1038 
1039  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1040 }

◆ TEST_P() [119/454]

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

Definition at line 326 of file aiks_dl_blur_unittests.cc.

326  {
327  DisplayListBuilder builder;
328  builder.Translate(0, -400);
329  DlPaint paint;
330 
331  Sigma sigma = Radius{120 * 3};
332  paint.setMaskFilter(
333  DlBlurMaskFilter::Make(DlBlurStyle::kNormal, sigma.sigma));
334  paint.setColor(DlColor::kRed());
335 
336  SkPath path = SkPath::Rect(SkRect::MakeLTRB(0, 0, 800, 800));
337  path.addCircle(0, 0, 0.5);
338  builder.DrawPath(path, paint);
339 
340  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
341 }

References impeller::Sigma::sigma.

◆ TEST_P() [120/454]

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

Definition at line 302 of file aiks_dl_blur_unittests.cc.

302  {
303  auto callback = [&]() -> sk_sp<DisplayList> {
304  static PlaygroundPoint playground_point(Point(400, 400), 20,
305  Color::Green());
306  auto point = DrawPlaygroundPoint(playground_point);
307 
308  DisplayListBuilder builder;
309  auto location = point - Point(400, 400);
310  builder.Translate(location.x, location.y);
311 
312  DlPaint paint;
313  Sigma sigma = Radius{120 * 3};
314  paint.setMaskFilter(
315  DlBlurMaskFilter::Make(DlBlurStyle::kNormal, sigma.sigma));
316  paint.setColor(DlColor::kRed());
317 
318  SkPath path = SkPath::Rect(SkRect::MakeLTRB(0, 0, 800, 800));
319  path.addCircle(0, 0, 0.5);
320  builder.DrawPath(path, paint);
321  return builder.Build();
322  };
323  ASSERT_TRUE(OpenPlaygroundHere(callback));
324 }

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

◆ TEST_P() [121/454]

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

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

Definition at line 39 of file aiks_dl_unittests.cc.

39  {
40  DisplayListBuilder builder;
41 
42  DlPaint paint;
43  paint.setColor(DlColor::kYellow());
44  paint.setBlendMode(DlBlendMode::kSrc);
45  builder.DrawPaint(paint);
46 
47  DlPaint save_paint;
48  save_paint.setBlendMode(DlBlendMode::kMultiply);
49  builder.SaveLayer(nullptr, &save_paint);
50 
51  DlPaint draw_paint;
52  draw_paint.setColor(DlColor::kCornflowerBlue().modulateOpacity(0.75f));
53  builder.DrawPaint(draw_paint);
54 
55  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
56 }

◆ TEST_P() [123/454]

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

Definition at line 58 of file aiks_dl_unittests.cc.

58  {
59  // Bug: https://github.com/flutter/flutter/issues/131576
60  DisplayListBuilder builder;
61 
62  DlPaint paint;
63  paint.setColor(DlColor::kYellow());
64  paint.setBlendMode(DlBlendMode::kSrc);
65  builder.DrawPaint(paint);
66 
67  auto filter = DlBlurImageFilter::Make(20.0, 20.0, DlTileMode::kDecal);
68  builder.SaveLayer(nullptr, nullptr, filter.get());
69 
70  DlPaint draw_paint;
71  draw_paint.setColor(DlColor::kCornflowerBlue());
72  builder.DrawPaint(draw_paint);
73 
74  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
75 }

◆ TEST_P() [124/454]

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, {0, 0}, DlImageSampling::kMipmapLinear,
286  &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  DlBlendColorFilter::Make(DlColor::RGBA(0.9, 0.5, 0.0, 1.0),
294  DlBlendMode::kSrcIn);
295  srcPaint.setColorFilter(color_filter);
296  }
297  builder.DrawImage(src_image, {0, 0}, DlImageSampling::kMipmapLinear,
298  &srcPaint);
299  }
300  builder.Restore();
301  }
302  return builder.Build();
303  };
304  ASSERT_TRUE(OpenPlaygroundHere(callback));
305 }

References impeller::AiksPlayground::ImGuiBegin(), and impeller::DlImageImpeller::Make().

◆ TEST_P() [125/454]

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  ASSERT_TRUE(SetCapabilities(mock_capabilities).ok());
342 
343  bool has_color_filter = true;
344  auto callback = [&]() -> sk_sp<DisplayList> {
345  if (AiksTest::ImGuiBegin("Controls", nullptr,
346  ImGuiWindowFlags_AlwaysAutoResize)) {
347  ImGui::Checkbox("has color filter", &has_color_filter);
348  ImGui::End();
349  }
350 
351  DisplayListBuilder builder;
352  builder.Scale(GetContentScale().x, GetContentScale().y);
353 
354  auto src_image =
355  DlImageImpeller::Make(CreateTextureForFixture("blend_mode_src.png"));
356  auto dst_image =
357  DlImageImpeller::Make(CreateTextureForFixture("blend_mode_dst.png"));
358 
359  std::vector<DlBlendMode> blend_modes = {
360  DlBlendMode::kScreen, DlBlendMode::kOverlay,
361  DlBlendMode::kDarken, DlBlendMode::kLighten,
362  DlBlendMode::kColorDodge, DlBlendMode::kColorBurn,
363  DlBlendMode::kHardLight, DlBlendMode::kSoftLight,
364  DlBlendMode::kDifference, DlBlendMode::kExclusion,
365  DlBlendMode::kMultiply, DlBlendMode::kHue,
366  DlBlendMode::kSaturation, DlBlendMode::kColor,
367  DlBlendMode::kLuminosity,
368  };
369 
370  for (uint32_t i = 0; i < blend_modes.size(); ++i) {
371  builder.Save();
372  builder.Translate((i % 5) * 200, (i / 5) * 200);
373  builder.Scale(0.4, 0.4);
374  {
375  DlPaint dstPaint;
376  builder.DrawImage(dst_image, {0, 0}, DlImageSampling::kMipmapLinear,
377  &dstPaint);
378  }
379  {
380  DlPaint srcPaint;
381  srcPaint.setBlendMode(blend_modes[i]);
382  if (has_color_filter) {
383  std::shared_ptr<const DlColorFilter> color_filter =
384  DlBlendColorFilter::Make(DlColor::RGBA(0.9, 0.5, 0.0, 1.0),
385  DlBlendMode::kMultiply);
386  srcPaint.setColorFilter(color_filter);
387  }
388  builder.DrawImage(src_image, {0, 0}, DlImageSampling::kMipmapLinear,
389  &srcPaint);
390  }
391  builder.Restore();
392  }
393  return builder.Build();
394  };
395  ASSERT_TRUE(OpenPlaygroundHere(callback));
396 }

References impeller::AiksPlayground::ImGuiBegin(), impeller::kMetal, and impeller::DlImageImpeller::Make().

◆ TEST_P() [126/454]

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, {0, 0}, DlImageSampling::kMipmapLinear,
229  &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  DlBlendColorFilter::Make(DlColor::RGBA(0.9, 0.5, 0.0, 1.0),
237  DlBlendMode::kSrcIn);
238  srcPaint.setColorFilter(color_filter);
239  }
240  builder.DrawImage(src_image, {0, 0}, DlImageSampling::kMipmapLinear,
241  &srcPaint);
242  }
243  builder.Restore();
244  }
245  return builder.Build();
246  };
247  ASSERT_TRUE(OpenPlaygroundHere(callback));
248 }

References impeller::AiksPlayground::ImGuiBegin(), and impeller::DlImageImpeller::Make().

◆ TEST_P() [127/454]

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

Definition at line 77 of file aiks_dl_unittests.cc.

77  {
78  DisplayListBuilder builder(GetCullRect(GetWindowSize()));
79 
80  const float matrix[20] = {
81  -1.0, 0, 0, 1.0, 0, //
82  0, -1.0, 0, 1.0, 0, //
83  0, 0, -1.0, 1.0, 0, //
84  1.0, 1.0, 1.0, 1.0, 0 //
85  };
86  auto filter = DlMatrixColorFilter::Make(matrix);
87 
88  DlPaint paint;
89  paint.setColorFilter(filter);
90  builder.SaveLayer(nullptr, &paint);
91 
92  builder.Translate(500, 300);
93  builder.Rotate(120); // 120 deg
94 
95  DlPaint draw_paint;
96  draw_paint.setColor(DlColor::kBlue());
97  builder.DrawRect(SkRect::MakeXYWH(100, 100, 200, 200), draw_paint);
98 
99  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
100 }

◆ TEST_P() [128/454]

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 774 of file aiks_dl_blend_unittests.cc.

774  {
775  // Compare with https://fiddle.skia.org/c/@BlendModes
776 
777  BlendModeSelection blend_modes = GetBlendModeSelection();
778 
779  auto draw_color_wheel = [](DisplayListBuilder& builder) -> void {
780  /// color_wheel_sampler: r=0 -> fuchsia, r=2pi/3 -> yellow, r=4pi/3 ->
781  /// cyan domain: r >= 0 (because modulo used is non euclidean)
782  auto color_wheel_sampler = [](Radians r) {
783  Scalar x = r.radians / k2Pi + 1;
784 
785  // https://www.desmos.com/calculator/6nhjelyoaj
786  auto color_cycle = [](Scalar x) {
787  Scalar cycle = std::fmod(x, 6.0f);
788  return std::max(0.0f, std::min(1.0f, 2 - std::abs(2 - cycle)));
789  };
790  return Color(color_cycle(6 * x + 1), //
791  color_cycle(6 * x - 1), //
792  color_cycle(6 * x - 3), //
793  1);
794  };
795 
796  DlPaint paint;
797  paint.setBlendMode(DlBlendMode::kSrcOver);
798 
799  // Draw a fancy color wheel for the backdrop.
800  // https://www.desmos.com/calculator/xw7kafthwd
801  const int max_dist = 900;
802  for (int i = 0; i <= 900; i++) {
803  Radians r(kPhi / k2Pi * i);
804  Scalar distance = r.radians / std::powf(4.12, 0.0026 * r.radians);
805  Scalar normalized_distance = static_cast<Scalar>(i) / max_dist;
806 
807  auto color = color_wheel_sampler(r).WithAlpha(1.0f - normalized_distance);
808  paint.setColor(
809  DlColor::RGBA(color.red, color.green, color.blue, color.alpha));
810  SkPoint position = SkPoint::Make(distance * std::sin(r.radians),
811  -distance * std::cos(r.radians));
812 
813  builder.DrawCircle(position, 9 + normalized_distance * 3, paint);
814  }
815  };
816 
817  auto callback = [&]() -> sk_sp<DisplayList> {
818  // UI state.
819  static bool cache_the_wheel = true;
820  static int current_blend_index = 3;
821  static float dst_alpha = 1;
822  static float src_alpha = 1;
823  static DlColor color0 = DlColor::kRed();
824  static DlColor color1 = DlColor::kGreen();
825  static DlColor color2 = DlColor::kBlue();
826 
827  if (AiksTest::ImGuiBegin("Controls", nullptr,
828  ImGuiWindowFlags_AlwaysAutoResize)) {
829  ImGui::Checkbox("Cache the wheel", &cache_the_wheel);
830  ImGui::ListBox("Blending mode", &current_blend_index,
831  blend_modes.blend_mode_names.data(),
832  blend_modes.blend_mode_names.size());
833  ImGui::SliderFloat("Source alpha", &src_alpha, 0, 1);
834  ImGui::ColorEdit4("Color A", reinterpret_cast<float*>(&color0));
835  ImGui::ColorEdit4("Color B", reinterpret_cast<float*>(&color1));
836  ImGui::ColorEdit4("Color C", reinterpret_cast<float*>(&color2));
837  ImGui::SliderFloat("Destination alpha", &dst_alpha, 0, 1);
838  ImGui::End();
839  }
840 
841  DisplayListBuilder builder;
842 
843  DlPaint paint;
844  paint.setColor(DlColor::kWhite().withAlpha(dst_alpha * 255));
845  paint.setBlendMode(DlBlendMode::kSrc);
846  builder.SaveLayer(nullptr, &paint);
847  {
848  DlPaint paint;
849  paint.setColor(DlColor::kWhite());
850  builder.DrawPaint(paint);
851 
852  builder.SaveLayer(nullptr, nullptr);
853  builder.Scale(GetContentScale().x, GetContentScale().y);
854  builder.Translate(500, 400);
855  builder.Scale(3, 3);
856  draw_color_wheel(builder);
857  builder.Restore();
858  }
859  builder.Restore();
860 
861  builder.Scale(GetContentScale().x, GetContentScale().y);
862  builder.Translate(500, 400);
863  builder.Scale(3, 3);
864 
865  // Draw 3 circles to a subpass and blend it in.
866  DlPaint save_paint;
867  save_paint.setColor(DlColor::kWhite().withAlpha(src_alpha * 255));
868  save_paint.setBlendMode(static_cast<DlBlendMode>(
869  blend_modes.blend_mode_values[current_blend_index]));
870  builder.SaveLayer(nullptr, &save_paint);
871  {
872  DlPaint paint;
873  paint.setBlendMode(DlBlendMode::kPlus);
874  const Scalar x = std::sin(k2Pi / 3);
875  const Scalar y = -std::cos(k2Pi / 3);
876  paint.setColor(color0);
877  builder.DrawCircle(SkPoint::Make(-x * 45, y * 45), 65, paint);
878  paint.setColor(color1);
879  builder.DrawCircle(SkPoint::Make(0, -45), 65, paint);
880  paint.setColor(color2);
881  builder.DrawCircle(SkPoint::Make(x * 45, y * 45), 65, paint);
882  }
883  builder.Restore();
884 
885  return builder.Build();
886  };
887 
888  ASSERT_TRUE(OpenPlaygroundHere(callback));
889 }

References impeller::testing::BlendModeSelection::blend_mode_names, impeller::testing::BlendModeSelection::blend_mode_values, color, impeller::saturated::distance, GetBlendModeSelection(), impeller::AiksPlayground::ImGuiBegin(), impeller::k2Pi, impeller::kPhi, and impeller::Radians::radians.

◆ TEST_P() [129/454]

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

Definition at line 1114 of file aiks_dl_basic_unittests.cc.

1114  {
1115  DisplayListBuilder builder;
1116 
1117  // Render a texture directly.
1118  {
1119  auto image = DlImageImpeller::Make(CreateTextureForFixture("kalimba.jpg"));
1120 
1121  builder.Save();
1122  builder.Translate(100, 200);
1123  builder.Scale(0.5, 0.5);
1124  builder.DrawImage(image, SkPoint::Make(100.0, 100.0),
1125  DlImageSampling::kNearestNeighbor);
1126  builder.Restore();
1127  }
1128 
1129  // Render an offscreen rendered texture.
1130  {
1131  DlPaint alpha;
1132  alpha.setColor(DlColor::kRed().modulateOpacity(0.5));
1133 
1134  builder.SaveLayer(nullptr, &alpha);
1135 
1136  DlPaint paint;
1137  paint.setColor(DlColor::kRed());
1138  builder.DrawRect(SkRect::MakeXYWH(000, 000, 100, 100), paint);
1139  paint.setColor(DlColor::kGreen());
1140  builder.DrawRect(SkRect::MakeXYWH(020, 020, 100, 100), paint);
1141  paint.setColor(DlColor::kBlue());
1142  builder.DrawRect(SkRect::MakeXYWH(040, 040, 100, 100), paint);
1143 
1144  builder.Restore();
1145  }
1146 
1147  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1148 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [130/454]

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

Definition at line 1297 of file aiks_dl_basic_unittests.cc.

1297  {
1298  auto callback = [&]() -> sk_sp<DisplayList> {
1299  DisplayListBuilder builder;
1300  builder.Scale(GetContentScale().x, GetContentScale().y);
1301 
1302  DlPaint alpha;
1303  alpha.setColor(DlColor::kRed().modulateOpacity(0.5));
1304 
1305  auto current = Point{25, 25};
1306  const auto offset = Point{25, 25};
1307  const auto size = Size(100, 100);
1308 
1309  static PlaygroundPoint point_a(Point(40, 40), 10, Color::White());
1310  static PlaygroundPoint point_b(Point(160, 160), 10, Color::White());
1311  auto [b0, b1] = DrawPlaygroundLine(point_a, point_b);
1312  SkRect bounds = SkRect::MakeLTRB(b0.x, b0.y, b1.x, b1.y);
1313 
1314  DlPaint stroke_paint;
1315  stroke_paint.setColor(DlColor::kYellow());
1316  stroke_paint.setStrokeWidth(5);
1317  stroke_paint.setDrawStyle(DlDrawStyle::kStroke);
1318  builder.DrawRect(bounds, stroke_paint);
1319 
1320  builder.SaveLayer(&bounds, &alpha);
1321 
1322  DlPaint paint;
1323  paint.setColor(DlColor::kRed());
1324  builder.DrawRect(
1325  SkRect::MakeXYWH(current.x, current.y, size.width, size.height), paint);
1326 
1327  paint.setColor(DlColor::kGreen());
1328  current += offset;
1329  builder.DrawRect(
1330  SkRect::MakeXYWH(current.x, current.y, size.width, size.height), paint);
1331 
1332  paint.setColor(DlColor::kBlue());
1333  current += offset;
1334  builder.DrawRect(
1335  SkRect::MakeXYWH(current.x, current.y, size.width, size.height), paint);
1336 
1337  builder.Restore();
1338 
1339  return builder.Build();
1340  };
1341 
1342  ASSERT_TRUE(OpenPlaygroundHere(callback));
1343 }

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

◆ TEST_P() [131/454]

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

Definition at line 864 of file aiks_dl_unittests.cc.

864  {
865  flutter::DisplayListBuilder sub_builder(true);
866  sub_builder.DrawRect(SkRect::MakeXYWH(0, 0, 50, 50),
867  flutter::DlPaint(flutter::DlColor::kRed()));
868  auto display_list = sub_builder.Build();
869 
870  AiksContext context(GetContext(), nullptr);
871  RenderTarget render_target =
872  context.GetContentContext().GetRenderTargetCache()->CreateOffscreen(
873  *context.GetContext(), {2400, 1800}, 1);
874 
875  DisplayListBuilder builder;
876 
877  builder.Scale(2.0, 2.0);
878  builder.Translate(-93.0, 0.0);
879 
880  // clang-format off
881  builder.TransformFullPerspective(
882  0.8, -0.2, -0.1, -0.0,
883  0.0, 1.0, 0.0, 0.0,
884  1.4, 1.3, 1.0, 0.0,
885  63.2, 65.3, 48.6, 1.1
886  );
887  // clang-format on
888  builder.Translate(35.0, 75.0);
889  builder.DrawDisplayList(display_list, 1.0f);
890 
891  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
892 }

References impeller::AiksContext::GetContentContext(), impeller::AiksContext::GetContext(), and impeller::ContentContext::GetRenderTargetCache().

◆ TEST_P() [132/454]

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

Definition at line 219 of file aiks_dl_atlas_unittests.cc.

219  {
220  auto [texture_coordinates, transforms, atlas] = CreateDlTestData(this);
221 
222  std::vector<DlColor> colors;
223  colors.reserve(texture_coordinates.size());
224  for (auto i = 0u; i < texture_coordinates.size(); i++) {
225  colors.push_back(DlColor::ARGB(0.5, 1, 1, 1));
226  }
227  DlAtlasGeometry geom(atlas->impeller_texture(), transforms.data(),
228  texture_coordinates.data(), colors.data(),
229  transforms.size(), BlendMode::kSourceOver, {},
230  std::nullopt);
231 
232  EXPECT_TRUE(geom.ShouldUseBlend());
233  EXPECT_FALSE(geom.ShouldSkip());
234 
235  ContentContext context(GetContext(), nullptr);
236  auto vertex_buffer =
237  geom.CreateBlendVertexBuffer(context.GetTransientsBuffer());
238 
239  EXPECT_EQ(vertex_buffer.index_type, IndexType::kNone);
240  EXPECT_EQ(vertex_buffer.vertex_count, texture_coordinates.size() * 6);
241 }

References impeller::DlAtlasGeometry::CreateBlendVertexBuffer(), impeller::ContentContext::GetTransientsBuffer(), impeller::kNone, impeller::kSourceOver, impeller::DlAtlasGeometry::ShouldSkip(), and impeller::DlAtlasGeometry::ShouldUseBlend().

◆ TEST_P() [133/454]

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

Definition at line 243 of file aiks_dl_atlas_unittests.cc.

243  {
244  auto [texture_coordinates, transforms, atlas] = CreateDlTestData(this);
245 
246  std::vector<DlColor> colors;
247  colors.reserve(texture_coordinates.size());
248  for (auto i = 0u; i < texture_coordinates.size(); i++) {
249  colors.push_back(DlColor::ARGB(0.5, 1, 1, 1));
250  }
251  DlAtlasGeometry geom(atlas->impeller_texture(), transforms.data(),
252  texture_coordinates.data(), colors.data(),
253  transforms.size(), BlendMode::kSource, {}, std::nullopt);
254 
255  // Src blend mode means that colors would be ignored, even if provided.
256  EXPECT_FALSE(geom.ShouldUseBlend());
257  EXPECT_FALSE(geom.ShouldSkip());
258 }

References impeller::kSource, impeller::DlAtlasGeometry::ShouldSkip(), and impeller::DlAtlasGeometry::ShouldUseBlend().

◆ TEST_P() [134/454]

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

Definition at line 201 of file aiks_dl_atlas_unittests.cc.

201  {
202  auto [texture_coordinates, transforms, atlas] = CreateDlTestData(this);
203 
204  DlAtlasGeometry geom(atlas->impeller_texture(), transforms.data(),
205  texture_coordinates.data(), nullptr, transforms.size(),
206  BlendMode::kSourceOver, {}, std::nullopt);
207 
208  EXPECT_FALSE(geom.ShouldUseBlend());
209  EXPECT_FALSE(geom.ShouldSkip());
210 
211  ContentContext context(GetContext(), nullptr);
212  auto vertex_buffer =
213  geom.CreateSimpleVertexBuffer(context.GetTransientsBuffer());
214 
215  EXPECT_EQ(vertex_buffer.index_type, IndexType::kNone);
216  EXPECT_EQ(vertex_buffer.vertex_count, texture_coordinates.size() * 6);
217 }

References impeller::DlAtlasGeometry::CreateSimpleVertexBuffer(), impeller::ContentContext::GetTransientsBuffer(), impeller::kNone, impeller::kSourceOver, impeller::DlAtlasGeometry::ShouldSkip(), and impeller::DlAtlasGeometry::ShouldUseBlend().

◆ TEST_P() [135/454]

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

Definition at line 260 of file aiks_dl_atlas_unittests.cc.

260  {
261  auto [texture_coordinates, transforms, atlas] = CreateDlTestData(this);
262 
263  std::vector<DlColor> colors;
264  colors.reserve(texture_coordinates.size());
265  for (auto i = 0u; i < texture_coordinates.size(); i++) {
266  colors.push_back(DlColor::ARGB(0.5, 1, 1, 1));
267  }
268  DlAtlasGeometry geom(atlas->impeller_texture(), transforms.data(),
269  texture_coordinates.data(), colors.data(),
270  transforms.size(), BlendMode::kClear, {}, std::nullopt);
271  EXPECT_TRUE(geom.ShouldSkip());
272 }

References impeller::kClear, and impeller::DlAtlasGeometry::ShouldSkip().

◆ TEST_P() [136/454]

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  SkMatrix matrix = SkMatrix::Scale(0.3, 0.3);
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({100, 100}, 100, paint);
170  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
171 }

◆ TEST_P() [137/454]

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

Definition at line 155 of file aiks_dl_atlas_unittests.cc.

155  {
156  DisplayListBuilder builder;
157  // Draws the image as four squares stiched together.
158  auto [texture_coordinates, transforms, atlas] = CreateTestData(this);
159 
160  builder.Scale(0.25, 0.25);
161  builder.DrawAtlas(atlas, transforms.data(), texture_coordinates.data(),
162  /*colors=*/nullptr, /*count=*/4, DlBlendMode::kModulate,
163  DlImageSampling::kNearestNeighbor, /*cullRect=*/nullptr);
164 
165  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
166 }

◆ TEST_P() [138/454]

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

Definition at line 78 of file aiks_dl_atlas_unittests.cc.

78  {
79  DisplayListBuilder builder;
80  auto [texture_coordinates, transforms, atlas] = CreateTestData(this);
81 
82  builder.Scale(GetContentScale().x, GetContentScale().y);
83  builder.DrawAtlas(atlas, transforms.data(), texture_coordinates.data(),
84  /*colors=*/nullptr, /*count=*/4, DlBlendMode::kSrcOver,
85  DlImageSampling::kNearestNeighbor, nullptr);
86 
87  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
88 }

◆ TEST_P() [139/454]

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

Definition at line 138 of file aiks_dl_atlas_unittests.cc.

138  {
139  auto atlas = DlImageImpeller::Make(CreateTextureForFixture("bay_bridge.jpg"));
140  auto size = atlas->impeller_texture()->GetSize();
141  std::vector<SkRect> texture_coordinates = {
142  SkRect::MakeLTRB(0, 0, size.width, size.height)};
143  std::vector<SkRSXform> transforms = {MakeTranslation(0, 0)};
144 
145  DisplayListBuilder builder;
146  builder.Scale(GetContentScale().x, GetContentScale().y);
147  builder.DrawAtlas(atlas, transforms.data(), texture_coordinates.data(),
148  /*colors=*/nullptr, /*count=*/1, DlBlendMode::kSrcOver,
149  DlImageSampling::kNearestNeighbor, /*cullRect=*/nullptr);
150 
151  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
152 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [140/454]

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

Definition at line 184 of file aiks_dl_atlas_unittests.cc.

184  {
185  DisplayListBuilder builder;
186  EXPECT_EQ(GetContext()->GetCapabilities()->GetDefaultColorFormat(),
187  PixelFormat::kB10G10R10A10XR);
188 
189  // Draws the image as four squares stiched together.
190  auto [texture_coordinates, transforms, atlas] = CreateTestData(this);
191  std::vector<DlColor> colors = {DlColor::kRed(), DlColor::kGreen(),
192  DlColor::kBlue(), DlColor::kYellow()};
193 
194  builder.DrawAtlas(atlas, transforms.data(), texture_coordinates.data(),
195  colors.data(), /*count=*/4, DlBlendMode::kPlus,
196  DlImageSampling::kNearestNeighbor, /*cullRect=*/nullptr);
197 
198  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
199 }

References impeller::kB10G10R10A10XR.

◆ TEST_P() [141/454]

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

Definition at line 90 of file aiks_dl_atlas_unittests.cc.

90  {
91  DisplayListBuilder builder;
92  auto [texture_coordinates, transforms, atlas] = CreateTestData(this);
93 
94  std::vector<DlColor> colors = {DlColor::kRed(), DlColor::kGreen(),
95  DlColor::kBlue(), DlColor::kYellow()};
96 
97  builder.Scale(GetContentScale().x, GetContentScale().y);
98  builder.DrawAtlas(atlas, transforms.data(), texture_coordinates.data(),
99  colors.data(), /*count=*/4, DlBlendMode::kModulate,
100  DlImageSampling::kNearestNeighbor, /*cullRect=*/nullptr);
101 
102  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
103 }

◆ TEST_P() [142/454]

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

Definition at line 169 of file aiks_dl_atlas_unittests.cc.

169  {
170  DisplayListBuilder builder;
171  // Draws the image as four squares stiched together.
172  auto [texture_coordinates, transforms, atlas] = CreateTestData(this);
173  std::vector<DlColor> colors = {DlColor::kRed(), DlColor::kGreen(),
174  DlColor::kBlue(), DlColor::kYellow()};
175 
176  builder.Scale(0.25, 0.25);
177  builder.DrawAtlas(atlas, transforms.data(), texture_coordinates.data(),
178  colors.data(), /*count=*/4, DlBlendMode::kModulate,
179  DlImageSampling::kNearestNeighbor, /*cullRect=*/nullptr);
180 
181  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
182 }

◆ TEST_P() [143/454]

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

Definition at line 105 of file aiks_dl_atlas_unittests.cc.

105  {
106  DisplayListBuilder builder;
107  // Draws the image as four squares stiched together.
108  auto [texture_coordinates, transforms, atlas] = CreateTestData(this);
109 
110  std::vector<DlColor> colors = {DlColor::kRed(), DlColor::kGreen(),
111  DlColor::kBlue(), DlColor::kYellow()};
112 
113  builder.Scale(GetContentScale().x, GetContentScale().y);
114  builder.DrawAtlas(atlas, transforms.data(), texture_coordinates.data(),
115  colors.data(), /*count=*/4, DlBlendMode::kSrcATop,
116  DlImageSampling::kNearestNeighbor, /*cullRect=*/nullptr);
117 
118  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
119 }

◆ TEST_P() [144/454]

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

Definition at line 121 of file aiks_dl_atlas_unittests.cc.

121  {
122  DisplayListBuilder builder;
123  // Draws the image as four squares stiched together slightly
124  // opaque
125  auto [texture_coordinates, transforms, atlas] = CreateTestData(this);
126 
127  DlPaint paint;
128  paint.setAlpha(128);
129  builder.Scale(GetContentScale().x, GetContentScale().y);
130  builder.DrawAtlas(atlas, transforms.data(), texture_coordinates.data(),
131  /*colors=*/nullptr, 4, DlBlendMode::kSrcOver,
132  DlImageSampling::kNearestNeighbor, /*cullRect=*/nullptr,
133  &paint);
134 
135  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
136 }

◆ TEST_P() [145/454]

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({150, 100}, {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({100, 150}, {100, 250}, paint);
333  builder.DrawCircle({origin}, 35, paint);
334 
335  builder.DrawLine({250, 250}, {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  SkMatrix matrix = SkMatrix::Translate(-150, 75);
372  paint.setColorSource(std::make_shared<DlImageColorSource>(
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(), and impeller::Matrix::MakeRotationZ().

◆ TEST_P() [146/454]

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

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

Definition at line 65 of file aiks_dl_runtime_effect_unittests.cc.

65  {
66  struct FragUniforms {
67  Size size;
68  } frag_uniforms = {.size = Size::MakeWH(400, 400)};
69  auto uniform_data = std::make_shared<std::vector<uint8_t>>();
70  uniform_data->resize(sizeof(FragUniforms));
71  memcpy(uniform_data->data(), &frag_uniforms, sizeof(FragUniforms));
72 
73  DlPaint paint;
74  paint.setColorSource(
75  MakeRuntimeEffect(this, "gradient.frag.iplr", uniform_data));
76 
77  DisplayListBuilder builder;
78  builder.Save();
79  builder.Scale(GetContentScale().x, GetContentScale().y);
80  builder.DrawPaint(paint);
81  builder.Restore();
82 
83  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
84 }

References impeller::TSize< Scalar >::MakeWH().

◆ TEST_P() [148/454]

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

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

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

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

Definition at line 414 of file aiks_dl_text_unittests.cc.

414  {
415  DisplayListBuilder builder;
416 
417  Matrix matrix = Matrix(1.0, 0.0, 0.0, 0.0, //
418  0.0, 1.0, 0.0, 0.0, //
419  0.0, 0.0, 1.0, 0.01, //
420  0.0, 0.0, 0.0, 1.0) * //
421  Matrix::MakeRotationY({Degrees{10}});
422 
423  builder.Transform(SkM44::ColMajor(matrix.m));
424 
425  ASSERT_TRUE(RenderTextInCanvasSkia(GetContext(), builder, "Hello world",
426  "Roboto-Regular.ttf"));
427  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
428 }

References impeller::Matrix::m, RenderTextInCanvasSkia(), and impeller::Matrix::Transform().

◆ TEST_P() [152/454]

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

Definition at line 430 of file aiks_dl_text_unittests.cc.

430  {
431  DisplayListBuilder builder;
432 
433  Matrix matrix = Matrix(1.0, 0.0, 0.0, 0.0, //
434  0.0, 1.0, 0.0, 0.0, //
435  0.0, 0.0, 1.0, 0.01, //
436  0.0, 0.0, 0.0, 1.0) * //
437  Matrix::MakeRotationY({Degrees{10}});
438 
439  DlPaint save_paint;
440  SkRect window_bounds =
441  SkRect::MakeXYWH(0, 0, GetWindowSize().width, GetWindowSize().height);
442  // Note: bounds were not needed by the AIKS version, which may indicate a bug.
443  builder.SaveLayer(&window_bounds, &save_paint);
444  builder.Transform(SkM44::ColMajor(matrix.m));
445 
446  ASSERT_TRUE(RenderTextInCanvasSkia(GetContext(), builder, "Hello world",
447  "Roboto-Regular.ttf"));
448 
449  builder.Restore();
450  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
451 }

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

◆ TEST_P() [153/454]

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

Definition at line 260 of file aiks_dl_vertices_unittests.cc.

260  {
261  auto texture = CreateTextureForFixture("embarcadero.jpg");
262  auto dl_image = DlImageImpeller::Make(texture);
263  std::vector<SkPoint> positions = {SkPoint::Make(100, 300),
264  SkPoint::Make(200, 100),
265  SkPoint::Make(300, 300)};
266  std::vector<SkPoint> texture_coordinates = {
267  SkPoint::Make(0, 0), SkPoint::Make(100, 200), SkPoint::Make(200, 100)};
268 
269  auto vertices = flutter::DlVertices::Make(
270  flutter::DlVertexMode::kTriangles, 3, positions.data(),
271  texture_coordinates.data(), /*colors=*/nullptr);
272 
273  flutter::DisplayListBuilder builder;
274  flutter::DlPaint paint;
275 
276  auto image_source = flutter::DlImageColorSource(
277  dl_image, flutter::DlTileMode::kRepeat, flutter::DlTileMode::kRepeat);
278 
279  paint.setColorSource(&image_source);
280  builder.DrawVertices(vertices, flutter::DlBlendMode::kSrcOver, paint);
281 
282  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
283 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [154/454]

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

Definition at line 285 of file aiks_dl_vertices_unittests.cc.

286  {
287  auto texture = CreateTextureForFixture("embarcadero.jpg");
288  auto dl_image = DlImageImpeller::Make(texture);
289  std::vector<SkPoint> positions = {SkPoint::Make(100, 300),
290  SkPoint::Make(200, 100),
291  SkPoint::Make(300, 300)};
292  std::vector<flutter::DlColor> colors = {flutter::DlColor::kWhite(),
293  flutter::DlColor::kGreen(),
294  flutter::DlColor::kWhite()};
295  std::vector<SkPoint> texture_coordinates = {
296  SkPoint::Make(0, 0), SkPoint::Make(100, 200), SkPoint::Make(200, 100)};
297 
298  auto vertices = flutter::DlVertices::Make(
299  flutter::DlVertexMode::kTriangles, 3, positions.data(),
300  texture_coordinates.data(), colors.data());
301 
302  flutter::DisplayListBuilder builder;
303  flutter::DlPaint paint;
304 
305  auto image_source = flutter::DlImageColorSource(
306  dl_image, flutter::DlTileMode::kRepeat, flutter::DlTileMode::kRepeat);
307 
308  paint.setColorSource(&image_source);
309  builder.DrawVertices(vertices, flutter::DlBlendMode::kModulate, paint);
310 
311  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
312 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [155/454]

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

Definition at line 205 of file aiks_dl_vertices_unittests.cc.

205  {
206  std::vector<SkPoint> positions = {SkPoint::Make(100, 300),
207  SkPoint::Make(200, 100),
208  SkPoint::Make(300, 300)};
209 
210  auto vertices = flutter::DlVertices::Make(
211  flutter::DlVertexMode::kTriangles, 3, positions.data(),
212  /*texture_coordinates=*/nullptr, /*colors=*/nullptr);
213 
214  std::vector<flutter::DlColor> colors = {flutter::DlColor::kBlue(),
215  flutter::DlColor::kRed()};
216  const float stops[2] = {0.0, 1.0};
217 
218  auto linear = flutter::DlColorSource::MakeLinear(
219  {100.0, 100.0}, {300.0, 300.0}, 2, colors.data(), stops,
220  flutter::DlTileMode::kRepeat);
221 
222  flutter::DisplayListBuilder builder;
223  flutter::DlPaint paint;
224 
225  paint.setColorSource(linear);
226  builder.DrawVertices(vertices, flutter::DlBlendMode::kSrcOver, paint);
227 
228  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
229 }

◆ TEST_P() [156/454]

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

Definition at line 231 of file aiks_dl_vertices_unittests.cc.

231  {
232  std::vector<SkPoint> positions = {SkPoint::Make(100, 300),
233  SkPoint::Make(200, 100),
234  SkPoint::Make(300, 300)};
235  std::vector<SkPoint> texture_coordinates = {SkPoint::Make(300, 100),
236  SkPoint::Make(100, 200),
237  SkPoint::Make(300, 300)};
238 
239  auto vertices = flutter::DlVertices::Make(
240  flutter::DlVertexMode::kTriangles, 3, positions.data(),
241  texture_coordinates.data(), /*colors=*/nullptr);
242 
243  std::vector<flutter::DlColor> colors = {flutter::DlColor::kBlue(),
244  flutter::DlColor::kRed()};
245  const float stops[2] = {0.0, 1.0};
246 
247  auto linear = flutter::DlColorSource::MakeLinear(
248  {100.0, 100.0}, {300.0, 300.0}, 2, colors.data(), stops,
249  flutter::DlTileMode::kRepeat);
250 
251  flutter::DisplayListBuilder builder;
252  flutter::DlPaint paint;
253 
254  paint.setColorSource(linear);
255  builder.DrawVertices(vertices, flutter::DlBlendMode::kSrcOver, paint);
256 
257  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
258 }

◆ TEST_P() [157/454]

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

Definition at line 334 of file aiks_dl_vertices_unittests.cc.

334  {
335  std::vector<SkPoint> positions = {
336  SkPoint::Make(100, 300), SkPoint::Make(200, 100), SkPoint::Make(300, 300),
337  SkPoint::Make(200, 500)};
338  auto color = flutter::DlColor::kBlue().withAlpha(0x99);
339  std::vector<uint16_t> indices = {0, 1, 2, 0, 2, 3};
340  std::vector<flutter::DlColor> colors = {color, color, color, color};
341 
342  auto vertices = flutter::DlVertices::Make(
343  flutter::DlVertexMode::kTriangles, positions.size(), positions.data(),
344  /*texture_coordinates=*/nullptr, colors.data(), indices.size(),
345  indices.data());
346 
347  flutter::DisplayListBuilder builder;
348  flutter::DlPaint paint;
349  paint.setBlendMode(flutter::DlBlendMode::kSrcOver);
350  paint.setColor(flutter::DlColor::kRed());
351 
352  builder.DrawRect(SkRect::MakeLTRB(0, 0, 400, 400), paint);
353  builder.DrawVertices(vertices, flutter::DlBlendMode::kDst, paint);
354 
355  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
356 }

References color.

◆ TEST_P() [158/454]

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

Definition at line 314 of file aiks_dl_vertices_unittests.cc.

314  {
315  std::vector<SkPoint> positions = {
316  SkPoint::Make(100, 300), SkPoint::Make(200, 100), SkPoint::Make(300, 300),
317  SkPoint::Make(200, 500)};
318  std::vector<uint16_t> indices = {0, 1, 2, 0, 2, 3};
319 
320  auto vertices = flutter::DlVertices::Make(
321  flutter::DlVertexMode::kTriangles, positions.size(), positions.data(),
322  /*texture_coordinates=*/nullptr, /*colors=*/nullptr, indices.size(),
323  indices.data());
324 
325  flutter::DisplayListBuilder builder;
326  flutter::DlPaint paint;
327 
328  paint.setColor(flutter::DlColor::kRed());
329  builder.DrawVertices(vertices, flutter::DlBlendMode::kSrcOver, paint);
330 
331  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
332 }

◆ TEST_P() [159/454]

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

Definition at line 181 of file aiks_dl_vertices_unittests.cc.

181  {
182  // Use negative coordinates and then scale the transform by -1, -1 to make
183  // sure coverage is taking the transform into account.
184  std::vector<SkPoint> positions = {SkPoint::Make(-100, -300),
185  SkPoint::Make(-200, -100),
186  SkPoint::Make(-300, -300)};
187  std::vector<flutter::DlColor> colors = {flutter::DlColor::kWhite(),
188  flutter::DlColor::kGreen(),
189  flutter::DlColor::kWhite()};
190 
191  auto vertices = flutter::DlVertices::Make(
192  flutter::DlVertexMode::kTriangles, 3, positions.data(),
193  /*texture_coordinates=*/nullptr, colors.data());
194 
195  flutter::DisplayListBuilder builder;
196  flutter::DlPaint paint;
197 
198  paint.setColor(flutter::DlColor::kRed().modulateOpacity(0.5));
199  builder.Scale(-1, -1);
200  builder.DrawVertices(vertices, flutter::DlBlendMode::kSrcOver, paint);
201 
202  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
203 }

◆ TEST_P() [160/454]

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

Definition at line 387 of file aiks_dl_vertices_unittests.cc.

387  {
388  std::vector<SkPoint> positions_lt = {
389  SkPoint::Make(0, 0), //
390  SkPoint::Make(50, 0), //
391  SkPoint::Make(0, 50), //
392  SkPoint::Make(50, 50), //
393  };
394 
395  auto vertices_lt = flutter::DlVertices::Make(
396  flutter::DlVertexMode::kTriangleStrip, positions_lt.size(),
397  positions_lt.data(),
398  /*texture_coordinates=*/positions_lt.data(), /*colors=*/nullptr,
399  /*index_count=*/0,
400  /*indices=*/nullptr);
401 
402  std::vector<SkPoint> positions_rt = {
403  SkPoint::Make(50, 0), //
404  SkPoint::Make(100, 0), //
405  SkPoint::Make(50, 50), //
406  SkPoint::Make(100, 50), //
407  };
408 
409  auto vertices_rt = flutter::DlVertices::Make(
410  flutter::DlVertexMode::kTriangleStrip, positions_rt.size(),
411  positions_rt.data(),
412  /*texture_coordinates=*/positions_rt.data(), /*colors=*/nullptr,
413  /*index_count=*/0,
414  /*indices=*/nullptr);
415 
416  std::vector<SkPoint> positions_lb = {
417  SkPoint::Make(0, 50), //
418  SkPoint::Make(50, 50), //
419  SkPoint::Make(0, 100), //
420  SkPoint::Make(50, 100), //
421  };
422 
423  auto vertices_lb = flutter::DlVertices::Make(
424  flutter::DlVertexMode::kTriangleStrip, positions_lb.size(),
425  positions_lb.data(),
426  /*texture_coordinates=*/positions_lb.data(), /*colors=*/nullptr,
427  /*index_count=*/0,
428  /*indices=*/nullptr);
429 
430  std::vector<SkPoint> positions_rb = {
431  SkPoint::Make(50, 50), //
432  SkPoint::Make(100, 50), //
433  SkPoint::Make(50, 100), //
434  SkPoint::Make(100, 100), //
435  };
436 
437  auto vertices_rb = flutter::DlVertices::Make(
438  flutter::DlVertexMode::kTriangleStrip, positions_rb.size(),
439  positions_rb.data(),
440  /*texture_coordinates=*/positions_rb.data(), /*colors=*/nullptr,
441  /*index_count=*/0,
442  /*indices=*/nullptr);
443 
444  flutter::DisplayListBuilder builder;
445  flutter::DlPaint paint;
446  flutter::DlPaint rect_paint;
447  rect_paint.setColor(DlColor::kBlue());
448 
449  auto runtime_stages =
450  OpenAssetAsRuntimeStage("runtime_stage_simple.frag.iplr");
451 
452  auto runtime_stage =
453  runtime_stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
454  ASSERT_TRUE(runtime_stage);
455 
456  auto runtime_effect = DlRuntimeEffect::MakeImpeller(runtime_stage);
457  auto uniform_data = std::make_shared<std::vector<uint8_t>>();
458  auto color_source = flutter::DlColorSource::MakeRuntimeEffect(
459  runtime_effect, {}, uniform_data);
460 
461  paint.setColorSource(color_source);
462 
463  builder.Scale(GetContentScale().x, GetContentScale().y);
464  builder.Save();
465  builder.DrawRect(SkRect::MakeLTRB(0, 0, 100, 100), rect_paint);
466  builder.DrawVertices(vertices_lt, flutter::DlBlendMode::kSrcOver, paint);
467  builder.DrawVertices(vertices_rt, flutter::DlBlendMode::kSrcOver, paint);
468  builder.DrawVertices(vertices_lb, flutter::DlBlendMode::kSrcOver, paint);
469  builder.DrawVertices(vertices_rb, flutter::DlBlendMode::kSrcOver, paint);
470  builder.Restore();
471 
472  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
473 }

References impeller::PlaygroundBackendToRuntimeStageBackend().

◆ TEST_P() [161/454]

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

Definition at line 477 of file aiks_dl_vertices_unittests.cc.

478  {
479  std::vector<SkPoint> positions_lt = {
480  SkPoint::Make(200, 200), //
481  SkPoint::Make(250, 200), //
482  SkPoint::Make(200, 250), //
483  SkPoint::Make(250, 250), //
484  };
485 
486  auto vertices = flutter::DlVertices::Make(
487  flutter::DlVertexMode::kTriangleStrip, positions_lt.size(),
488  positions_lt.data(),
489  /*texture_coordinates=*/positions_lt.data(), /*colors=*/nullptr,
490  /*index_count=*/0,
491  /*indices=*/nullptr);
492 
493  flutter::DisplayListBuilder builder;
494  flutter::DlPaint paint;
495  flutter::DlPaint rect_paint;
496  rect_paint.setColor(DlColor::kBlue());
497 
498  auto runtime_stages =
499  OpenAssetAsRuntimeStage("runtime_stage_position.frag.iplr");
500 
501  auto runtime_stage =
502  runtime_stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
503  ASSERT_TRUE(runtime_stage);
504 
505  auto runtime_effect = DlRuntimeEffect::MakeImpeller(runtime_stage);
506  auto rect_data = std::vector<Rect>{Rect::MakeLTRB(200, 200, 250, 250)};
507 
508  auto uniform_data = std::make_shared<std::vector<uint8_t>>();
509  uniform_data->resize(rect_data.size() * sizeof(Rect));
510  memcpy(uniform_data->data(), rect_data.data(), uniform_data->size());
511 
512  auto color_source = flutter::DlColorSource::MakeRuntimeEffect(
513  runtime_effect, {}, uniform_data);
514 
515  paint.setColorSource(color_source);
516 
517  builder.Scale(GetContentScale().x, GetContentScale().y);
518  builder.DrawRect(SkRect::MakeLTRB(200, 200, 250, 250), rect_paint);
519  builder.DrawVertices(vertices, flutter::DlBlendMode::kSrcOver, paint);
520 
521  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
522 }

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

◆ TEST_P() [162/454]

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

Definition at line 358 of file aiks_dl_vertices_unittests.cc.

358  {
359  std::vector<SkPoint> positions = {
360  SkPoint::Make(100, 300), SkPoint::Make(200, 100), SkPoint::Make(300, 300),
361  SkPoint::Make(200, 500)};
362  std::vector<uint16_t> indices = {0, 1, 2, 0, 2, 3, 99, 100, 101};
363 
364  auto vertices = flutter::DlVertices::Make(
365  flutter::DlVertexMode::kTriangles, positions.size(), positions.data(),
366  /*texture_coordinates=*/nullptr, /*colors=*/nullptr, indices.size(),
367  indices.data());
368 
369  EXPECT_EQ(vertices->bounds(), SkRect::MakeLTRB(100, 100, 300, 500));
370 
371  flutter::DisplayListBuilder builder;
372  flutter::DlPaint paint;
373  paint.setBlendMode(flutter::DlBlendMode::kSrcOver);
374  paint.setColor(flutter::DlColor::kRed());
375 
376  builder.DrawRect(SkRect::MakeLTRB(0, 0, 400, 400), paint);
377  builder.DrawVertices(vertices, flutter::DlBlendMode::kSrc, paint);
378 
379  AiksContext renderer(GetContext(), nullptr);
380  std::shared_ptr<Texture> image =
381  DisplayListToTexture(builder.Build(), {1024, 768}, renderer);
382  EXPECT_TRUE(image);
383 }

References impeller::DisplayListToTexture().

◆ TEST_P() [163/454]

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

Definition at line 1042 of file aiks_dl_basic_unittests.cc.

1042  {
1043  DisplayListBuilder builder;
1044  builder.Scale(GetContentScale().x, GetContentScale().y);
1045 
1046  DlPaint paint;
1047  paint.setColor(DlColor::kRed());
1048  builder.DrawPaint(paint);
1049  builder.ClipRect(SkRect::MakeXYWH(100, 100, 200, 200));
1050  paint.setColor(DlColor::kBlue());
1051  builder.SaveLayer(nullptr, &paint);
1052  builder.Restore();
1053 
1054  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1055 }

◆ TEST_P() [164/454]

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

Definition at line 1057 of file aiks_dl_basic_unittests.cc.

1057  {
1058  DisplayListBuilder builder;
1059  builder.Scale(GetContentScale().x, GetContentScale().y);
1060  auto image = DlImageImpeller::Make(CreateTextureForFixture("airplane.jpg"));
1061  builder.DrawImage(image, {10, 10}, {});
1062  builder.ClipRect(SkRect::MakeXYWH(100, 100, 200, 200));
1063 
1064  DlPaint paint;
1065  paint.setBlendMode(DlBlendMode::kClear);
1066  builder.SaveLayer(nullptr, &paint);
1067  builder.Restore();
1068 
1069  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1070 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [165/454]

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

Definition at line 1461 of file aiks_dl_basic_unittests.cc.

1461  {
1462  DisplayListBuilder builder;
1463 
1464  builder.Scale(GetContentScale().x, GetContentScale().y);
1465  DlPaint paint;
1466  paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kNormal, 1));
1467 
1468  DlPaint save_paint;
1469  save_paint.setColor(DlColor::kWhite());
1470  builder.DrawPaint(save_paint);
1471 
1472  paint.setColor(DlColor::kBlue());
1473  for (int i = 0; i < 5; i++) {
1474  Scalar y = i * 125;
1475  Scalar y_radius = i * 15;
1476  for (int j = 0; j < 5; j++) {
1477  Scalar x = j * 125;
1478  Scalar x_radius = j * 15;
1479  builder.DrawRRect(
1480  SkRRect::MakeRectXY(SkRect::MakeXYWH(x + 50, y + 50, 100.0f, 100.0f),
1481  x_radius, y_radius),
1482  paint);
1483  }
1484  }
1485 
1486  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1487 }

◆ TEST_P() [166/454]

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

Definition at line 716 of file aiks_dl_gradient_unittests.cc.

716  {
717  DisplayListBuilder builder;
718  DlPaint paint;
719  builder.Translate(100.0f, 0);
720 
721  std::vector<DlColor> colors = {DlColor::kRed(), DlColor::kBlue(),
722  DlColor::kGreen()};
723  std::vector<Scalar> stops = {0.0, 0.1, 1.0};
724 
725  paint.setColorSource(DlColorSource::MakeLinear({0, 0}, {300, 0}, stops.size(),
726  colors.data(), stops.data(),
727  DlTileMode::kClamp));
728 
729  paint.setColor(DlColor::kWhite());
730  builder.DrawRect(SkRect::MakeXYWH(0, 0, 300, 300), paint);
731  builder.Translate(400, 0);
732  builder.DrawRRect(SkRRect::MakeRectXY(SkRect::MakeXYWH(0, 0, 300, 300), 4, 4),
733  paint);
734 
735  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
736 }

◆ TEST_P() [167/454]

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

Definition at line 762 of file aiks_dl_gradient_unittests.cc.

762  {
763  DisplayListBuilder builder;
764  DlPaint paint;
765  builder.Translate(100.0f, 0);
766 
767  std::vector<DlColor> colors = {DlColor::kRed(), DlColor::kBlue(),
768  DlColor::kGreen()};
769  std::vector<Scalar> stops = {0.0, 0.1, 1.0};
770 
771  paint.setColorSource(DlColorSource::MakeLinear({300, 0}, {0, 0}, stops.size(),
772  colors.data(), stops.data(),
773  DlTileMode::kClamp));
774 
775  paint.setColor(DlColor::kWhite());
776  builder.DrawRect(SkRect::MakeXYWH(0, 0, 300, 300), paint);
777  builder.Translate(400, 0);
778  builder.DrawRRect(SkRRect::MakeRectXY(SkRect::MakeXYWH(0, 0, 300, 300), 4, 4),
779  paint);
780 
781  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
782 }

◆ TEST_P() [168/454]

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

Definition at line 739 of file aiks_dl_gradient_unittests.cc.

739  {
740  DisplayListBuilder builder;
741  DlPaint paint;
742  builder.Translate(100.0f, 0);
743 
744  std::vector<DlColor> colors = {DlColor::kRed(), DlColor::kBlue(),
745  DlColor::kGreen()};
746  std::vector<Scalar> stops = {0.0, 0.1, 1.0};
747 
748  paint.setColorSource(DlColorSource::MakeLinear({0, 0}, {0, 300}, stops.size(),
749  colors.data(), stops.data(),
750  DlTileMode::kClamp));
751 
752  paint.setColor(DlColor::kWhite());
753  builder.DrawRect(SkRect::MakeXYWH(0, 0, 300, 300), paint);
754  builder.Translate(400, 0);
755  builder.DrawRRect(SkRRect::MakeRectXY(SkRect::MakeXYWH(0, 0, 300, 300), 4, 4),
756  paint);
757 
758  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
759 }

◆ TEST_P() [169/454]

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

Definition at line 785 of file aiks_dl_gradient_unittests.cc.

785  {
786  DisplayListBuilder builder;
787  DlPaint paint;
788  builder.Translate(100.0f, 0);
789 
790  std::vector<DlColor> colors = {DlColor::kRed(), DlColor::kBlue(),
791  DlColor::kGreen()};
792  std::vector<Scalar> stops = {0.0, 0.1, 1.0};
793 
794  paint.setColorSource(DlColorSource::MakeLinear({0, 300}, {0, 0}, stops.size(),
795  colors.data(), stops.data(),
796  DlTileMode::kClamp));
797 
798  paint.setColor(DlColor::kWhite());
799  builder.DrawRect(SkRect::MakeXYWH(0, 0, 300, 300), paint);
800  builder.Translate(400, 0);
801  builder.DrawRRect(SkRRect::MakeRectXY(SkRect::MakeXYWH(0, 0, 300, 300), 4, 4),
802  paint);
803 
804  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
805 }

◆ TEST_P() [170/454]

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

Definition at line 415 of file aiks_dl_basic_unittests.cc.

415  {
416  DisplayListBuilder builder;
417  builder.Scale(GetContentScale().x, GetContentScale().y);
418  DlPaint paint;
419  const int color_count = 3;
420  DlColor colors[color_count] = {
421  DlColor::kBlue(),
422  DlColor::kGreen(),
423  DlColor::RGBA(220.0f / 255.0f, 20.0f / 255.0f, 60.0f / 255.0f, 1.0f),
424  };
425 
426  paint.setColor(DlColor::kWhite());
427  builder.DrawPaint(paint);
428 
429  int c_index = 0;
430  int radius = 600;
431  while (radius > 0) {
432  paint.setColor(colors[(c_index++) % color_count]);
433  builder.DrawCircle({10, 10}, radius, paint);
434  if (radius > 30) {
435  radius -= 10;
436  } else {
437  radius -= 2;
438  }
439  }
440 
441  DlColor gradient_colors[7] = {
442  DlColor::RGBA(0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0),
443  DlColor::RGBA(0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0),
444  DlColor::RGBA(0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0),
445  DlColor::RGBA(0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0),
446  DlColor::RGBA(0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0),
447  DlColor::RGBA(0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0),
448  DlColor::RGBA(0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0),
449  };
450  DlScalar stops[7] = {
451  0.0,
452  (1.0 / 6.0) * 1,
453  (1.0 / 6.0) * 2,
454  (1.0 / 6.0) * 3,
455  (1.0 / 6.0) * 4,
456  (1.0 / 6.0) * 5,
457  1.0,
458  };
459  auto texture = CreateTextureForFixture("airplane.jpg",
460  /*enable_mipmapping=*/true);
461  auto image = DlImageImpeller::Make(texture);
462 
463  paint.setColorSource(DlColorSource::MakeRadial(
464  {500, 600}, 75, 7, gradient_colors, stops, DlTileMode::kMirror));
465  builder.DrawCircle({500, 600}, 100, paint);
466 
467  SkMatrix local_matrix = SkMatrix::Translate(700, 200);
468  DlImageColorSource image_source(
469  image, DlTileMode::kRepeat, DlTileMode::kRepeat,
470  DlImageSampling::kNearestNeighbor, &local_matrix);
471  paint.setColorSource(&image_source);
472  builder.DrawCircle({800, 300}, 100, paint);
473 
474  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
475 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [171/454]

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

Definition at line 544 of file aiks_dl_basic_unittests.cc.

544  {
545  DisplayListBuilder builder;
546  builder.Scale(GetContentScale().x, GetContentScale().y);
547  DlPaint paint;
548  const int color_count = 3;
549  DlColor colors[color_count] = {
550  DlColor::kBlue(),
551  DlColor::kGreen(),
552  DlColor::RGBA(220.0f / 255.0f, 20.0f / 255.0f, 60.0f / 255.0f, 1.0f),
553  };
554 
555  paint.setColor(DlColor::kWhite());
556  builder.DrawPaint(paint);
557 
558  int c_index = 0;
559  int long_radius = 600;
560  int short_radius = 600;
561  while (long_radius > 0 && short_radius > 0) {
562  paint.setColor(colors[(c_index++) % color_count]);
563  builder.DrawOval(SkRect::MakeXYWH(10 - long_radius, 10 - short_radius,
564  long_radius * 2, short_radius * 2),
565  paint);
566  builder.DrawOval(SkRect::MakeXYWH(1000 - short_radius, 750 - long_radius,
567  short_radius * 2, long_radius * 2),
568  paint);
569  if (short_radius > 30) {
570  short_radius -= 10;
571  long_radius -= 5;
572  } else {
573  short_radius -= 2;
574  long_radius -= 1;
575  }
576  }
577 
578  DlColor gradient_colors[7] = {
579  DlColor::RGBA(0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0),
580  DlColor::RGBA(0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0),
581  DlColor::RGBA(0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0),
582  DlColor::RGBA(0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0),
583  DlColor::RGBA(0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0),
584  DlColor::RGBA(0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0),
585  DlColor::RGBA(0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0),
586  };
587  DlScalar stops[7] = {
588  0.0,
589  (1.0 / 6.0) * 1,
590  (1.0 / 6.0) * 2,
591  (1.0 / 6.0) * 3,
592  (1.0 / 6.0) * 4,
593  (1.0 / 6.0) * 5,
594  1.0,
595  };
596  auto texture = CreateTextureForFixture("airplane.jpg",
597  /*enable_mipmapping=*/true);
598  auto image = DlImageImpeller::Make(texture);
599 
600  paint.setColor(DlColor::kWhite().modulateOpacity(0.5));
601 
602  paint.setColorSource(DlColorSource::MakeRadial(
603  {300, 650}, 75, 7, gradient_colors, stops, DlTileMode::kMirror));
604  builder.DrawOval(SkRect::MakeXYWH(200, 625, 200, 50), paint);
605  builder.DrawOval(SkRect::MakeXYWH(275, 550, 50, 200), paint);
606 
607  SkMatrix local_matrix = SkMatrix::Translate(610, 15);
608  DlImageColorSource image_source(
609  image, DlTileMode::kRepeat, DlTileMode::kRepeat,
610  DlImageSampling::kNearestNeighbor, &local_matrix);
611  paint.setColorSource(&image_source);
612  builder.DrawOval(SkRect::MakeXYWH(610, 90, 200, 50), paint);
613  builder.DrawOval(SkRect::MakeXYWH(685, 15, 50, 200), paint);
614 
615  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
616 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [172/454]

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

Definition at line 1193 of file aiks_dl_basic_unittests.cc.

1193  {
1194  DisplayListBuilder builder;
1195  builder.Scale(GetContentScale().x, GetContentScale().y);
1196 
1197  DlPaint paint;
1198  const int color_count = 3;
1199  DlColor colors[color_count] = {
1200  DlColor::kBlue(),
1201  DlColor::kGreen(),
1202  DlColor::ARGB(1.0, 220.0f / 255.0f, 20.0f / 255.0f, 60.0f / 255.0f),
1203  };
1204 
1205  paint.setColor(DlColor::kWhite());
1206  builder.DrawPaint(paint);
1207 
1208  auto draw_rrect_as_path = [&builder](const SkRect& rect, Scalar x, Scalar y,
1209  const DlPaint& paint) {
1210  SkPath path;
1211  path.addRoundRect(rect, x, y);
1212  builder.DrawPath(path, paint);
1213  };
1214 
1215  int c_index = 0;
1216  for (int i = 0; i < 4; i++) {
1217  for (int j = 0; j < 4; j++) {
1218  paint.setColor(colors[(c_index++) % color_count]);
1219  draw_rrect_as_path(SkRect::MakeXYWH(i * 100 + 10, j * 100 + 20, 80, 80),
1220  i * 5 + 10, j * 5 + 10, paint);
1221  }
1222  }
1223  paint.setColor(colors[(c_index++) % color_count]);
1224  draw_rrect_as_path(SkRect::MakeXYWH(10, 420, 380, 80), 40, 40, paint);
1225  paint.setColor(colors[(c_index++) % color_count]);
1226  draw_rrect_as_path(SkRect::MakeXYWH(410, 20, 80, 380), 40, 40, paint);
1227 
1228  std::vector<DlColor> gradient_colors = {
1229  DlColor::RGBA(0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0),
1230  DlColor::RGBA(0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0),
1231  DlColor::RGBA(0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0),
1232  DlColor::RGBA(0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0),
1233  DlColor::RGBA(0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0),
1234  DlColor::RGBA(0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0),
1235  DlColor::RGBA(0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0)};
1236  std::vector<Scalar> stops = {
1237  0.0,
1238  (1.0 / 6.0) * 1,
1239  (1.0 / 6.0) * 2,
1240  (1.0 / 6.0) * 3,
1241  (1.0 / 6.0) * 4,
1242  (1.0 / 6.0) * 5,
1243  1.0,
1244  };
1245  auto texture = DlImageImpeller::Make(
1246  CreateTextureForFixture("airplane.jpg",
1247  /*enable_mipmapping=*/true));
1248 
1249  paint.setColor(DlColor::kWhite().modulateOpacity(0.1));
1250  paint.setColorSource(DlColorSource::MakeRadial(
1251  /*center=*/{550, 550},
1252  /*radius=*/75,
1253  /*stop_count=*/gradient_colors.size(),
1254  /*colors=*/gradient_colors.data(),
1255  /*stops=*/stops.data(),
1256  /*tile_mode=*/DlTileMode::kMirror));
1257  for (int i = 1; i <= 10; i++) {
1258  int j = 11 - i;
1259  draw_rrect_as_path(SkRect::MakeLTRB(550 - i * 20, 550 - j * 20, //
1260  550 + i * 20, 550 + j * 20),
1261  i * 10, j * 10, paint);
1262  }
1263  paint.setColor(DlColor::kWhite().modulateOpacity(0.5));
1264  paint.setColorSource(DlColorSource::MakeRadial(
1265  /*center=*/{200, 650},
1266  /*radius=*/75,
1267  /*stop_count=*/gradient_colors.size(),
1268  /*colors=*/gradient_colors.data(),
1269  /*stops=*/stops.data(),
1270  /*tile_mode=*/DlTileMode::kMirror));
1271  draw_rrect_as_path(SkRect::MakeLTRB(100, 610, 300, 690), 40, 40, paint);
1272  draw_rrect_as_path(SkRect::MakeLTRB(160, 550, 240, 750), 40, 40, paint);
1273 
1274  auto matrix = SkMatrix::Translate(520, 20);
1275  paint.setColor(DlColor::kWhite().modulateOpacity(0.1));
1276  paint.setColorSource(std::make_shared<DlImageColorSource>(
1277  texture, DlTileMode::kRepeat, DlTileMode::kRepeat,
1278  DlImageSampling::kMipmapLinear, &matrix));
1279  for (int i = 1; i <= 10; i++) {
1280  int j = 11 - i;
1281  draw_rrect_as_path(SkRect::MakeLTRB(720 - i * 20, 220 - j * 20, //
1282  720 + i * 20, 220 + j * 20),
1283  i * 10, j * 10, paint);
1284  }
1285  matrix = SkMatrix::Translate(800, 300);
1286  paint.setColor(DlColor::kWhite().modulateOpacity(0.5));
1287  paint.setColorSource(std::make_shared<DlImageColorSource>(
1288  texture, DlTileMode::kRepeat, DlTileMode::kRepeat,
1289  DlImageSampling::kMipmapLinear, &matrix));
1290 
1291  draw_rrect_as_path(SkRect::MakeLTRB(800, 410, 1000, 490), 40, 40, paint);
1292  draw_rrect_as_path(SkRect::MakeLTRB(860, 350, 940, 550), 40, 40, paint);
1293 
1294  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1295 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [173/454]

impeller::testing::TEST_P ( AiksTest  ,
FilledRoundRectsRenderCorrectly   
)

Definition at line 618 of file aiks_dl_basic_unittests.cc.

618  {
619  DisplayListBuilder builder;
620  builder.Scale(GetContentScale().x, GetContentScale().y);
621  DlPaint paint;
622  const int color_count = 3;
623  DlColor colors[color_count] = {
624  DlColor::kBlue(),
625  DlColor::kGreen(),
626  DlColor::RGBA(220.0f / 255.0f, 20.0f / 255.0f, 60.0f / 255.0f, 1.0f),
627  };
628 
629  paint.setColor(DlColor::kWhite());
630  builder.DrawPaint(paint);
631 
632  int c_index = 0;
633  for (int i = 0; i < 4; i++) {
634  for (int j = 0; j < 4; j++) {
635  paint.setColor(colors[(c_index++) % color_count]);
636  builder.DrawRRect(
637  SkRRect::MakeRectXY(
638  SkRect::MakeXYWH(i * 100 + 10, j * 100 + 20, 80, 80), //
639  i * 5 + 10, j * 5 + 10),
640  paint);
641  }
642  }
643  paint.setColor(colors[(c_index++) % color_count]);
644  builder.DrawRRect(
645  SkRRect::MakeRectXY(SkRect::MakeXYWH(10, 420, 380, 80), 40, 40), paint);
646  paint.setColor(colors[(c_index++) % color_count]);
647  builder.DrawRRect(
648  SkRRect::MakeRectXY(SkRect::MakeXYWH(410, 20, 80, 380), 40, 40), paint);
649 
650  DlColor gradient_colors[7] = {
651  DlColor::RGBA(0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0),
652  DlColor::RGBA(0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0),
653  DlColor::RGBA(0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0),
654  DlColor::RGBA(0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0),
655  DlColor::RGBA(0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0),
656  DlColor::RGBA(0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0),
657  DlColor::RGBA(0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0),
658  };
659  DlScalar stops[7] = {
660  0.0,
661  (1.0 / 6.0) * 1,
662  (1.0 / 6.0) * 2,
663  (1.0 / 6.0) * 3,
664  (1.0 / 6.0) * 4,
665  (1.0 / 6.0) * 5,
666  1.0,
667  };
668  auto texture = CreateTextureForFixture("airplane.jpg",
669  /*enable_mipmapping=*/true);
670  auto image = DlImageImpeller::Make(texture);
671 
672  paint.setColor(DlColor::kWhite().modulateOpacity(0.1));
673  paint.setColorSource(DlColorSource::MakeRadial(
674  {550, 550}, 75, 7, gradient_colors, stops, DlTileMode::kMirror));
675  for (int i = 1; i <= 10; i++) {
676  int j = 11 - i;
677  builder.DrawRRect(
678  SkRRect::MakeRectXY(SkRect::MakeLTRB(550 - i * 20, 550 - j * 20, //
679  550 + i * 20, 550 + j * 20),
680  i * 10, j * 10),
681  paint);
682  }
683 
684  paint.setColor(DlColor::kWhite().modulateOpacity(0.5));
685  paint.setColorSource(DlColorSource::MakeRadial(
686  {200, 650}, 75, 7, gradient_colors, stops, DlTileMode::kMirror));
687  paint.setColor(DlColor::kWhite().modulateOpacity(0.5));
688  builder.DrawRRect(
689  SkRRect::MakeRectXY(SkRect::MakeLTRB(100, 610, 300, 690), 40, 40), paint);
690  builder.DrawRRect(
691  SkRRect::MakeRectXY(SkRect::MakeLTRB(160, 550, 240, 750), 40, 40), paint);
692 
693  paint.setColor(DlColor::kWhite().modulateOpacity(0.1));
694  SkMatrix local_matrix = SkMatrix::Translate(520, 20);
695  DlImageColorSource image_source(
696  image, DlTileMode::kRepeat, DlTileMode::kRepeat,
697  DlImageSampling::kNearestNeighbor, &local_matrix);
698  paint.setColorSource(&image_source);
699  for (int i = 1; i <= 10; i++) {
700  int j = 11 - i;
701  builder.DrawRRect(
702  SkRRect::MakeRectXY(SkRect::MakeLTRB(720 - i * 20, 220 - j * 20, //
703  720 + i * 20, 220 + j * 20),
704  i * 10, j * 10),
705  paint);
706  }
707 
708  paint.setColor(DlColor::kWhite().modulateOpacity(0.5));
709  local_matrix = SkMatrix::Translate(800, 300);
710  DlImageColorSource image_source2(
711  image, DlTileMode::kRepeat, DlTileMode::kRepeat,
712  DlImageSampling::kNearestNeighbor, &local_matrix);
713  paint.setColorSource(&image_source2);
714  builder.DrawRRect(
715  SkRRect::MakeRectXY(SkRect::MakeLTRB(800, 410, 1000, 490), 40, 40),
716  paint);
717  builder.DrawRRect(
718  SkRRect::MakeRectXY(SkRect::MakeLTRB(860, 350, 940, 550), 40, 40), paint);
719 
720  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
721 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [174/454]

impeller::testing::TEST_P ( AiksTest  ,
ForegroundAdvancedBlendAppliesTransformCorrectly   
)

Definition at line 733 of file aiks_dl_blend_unittests.cc.

733  {
734  auto texture = CreateTextureForFixture("airplane.jpg",
735  /*enable_mipmapping=*/true);
736 
737  DisplayListBuilder builder;
738  builder.Rotate(30);
739 
740  DlPaint image_paint;
741  image_paint.setColorFilter(DlBlendColorFilter::Make(
742  DlColor::RGBA(255.0f / 255.0f, 165.0f / 255.0f, 0.0f / 255.0f, 1.0f),
743  DlBlendMode::kColorDodge));
744 
745  builder.DrawImage(DlImageImpeller::Make(texture), {200, 200},
746  DlImageSampling::kMipmapLinear, &image_paint);
747 
748  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
749 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [175/454]

impeller::testing::TEST_P ( AiksTest  ,
ForegroundBlendSubpassCollapseOptimization   
)

Definition at line 468 of file aiks_dl_blend_unittests.cc.

468  {
469  DisplayListBuilder builder;
470 
471  DlPaint save_paint;
472  save_paint.setColorFilter(
473  DlBlendColorFilter::Make(DlColor::kRed(), DlBlendMode::kColorDodge));
474  builder.SaveLayer(nullptr, &save_paint);
475 
476  builder.Translate(500, 300);
477  builder.Rotate(120);
478 
479  DlPaint paint;
480  paint.setColor(DlColor::kBlue());
481  builder.DrawRect(SkRect::MakeXYWH(100, 100, 200, 200), paint);
482 
483  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
484 }

◆ TEST_P() [176/454]

impeller::testing::TEST_P ( AiksTest  ,
ForegroundPipelineBlendAppliesTransformCorrectly   
)

Definition at line 715 of file aiks_dl_blend_unittests.cc.

715  {
716  auto texture = CreateTextureForFixture("airplane.jpg",
717  /*enable_mipmapping=*/true);
718 
719  DisplayListBuilder builder;
720  builder.Rotate(30);
721 
722  DlPaint image_paint;
723  image_paint.setColorFilter(DlBlendColorFilter::Make(
724  DlColor::RGBA(255.0f / 255.0f, 165.0f / 255.0f, 0.0f / 255.0f, 1.0f),
725  DlBlendMode::kSrcIn));
726 
727  builder.DrawImage(DlImageImpeller::Make(texture), {200, 200},
728  DlImageSampling::kMipmapLinear, &image_paint);
729 
730  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
731 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [177/454]

impeller::testing::TEST_P ( AiksTest  ,
FormatSRGB   
)

Definition at line 1106 of file aiks_dl_basic_unittests.cc.

1106  {
1107  PixelFormat pixel_format =
1108  GetContext()->GetCapabilities()->GetDefaultColorFormat();
1109  EXPECT_TRUE(pixel_format == PixelFormat::kR8G8B8A8UNormInt ||
1110  pixel_format == PixelFormat::kB8G8R8A8UNormInt)
1111  << "pixel format: " << PixelFormatToString(pixel_format);
1112 }

References impeller::kB8G8R8A8UNormInt, impeller::kR8G8B8A8UNormInt, and impeller::PixelFormatToString().

◆ TEST_P() [178/454]

impeller::testing::TEST_P ( AiksTest  ,
FormatWideGamut   
)

Definition at line 1101 of file aiks_dl_basic_unittests.cc.

1101  {
1102  EXPECT_EQ(GetContext()->GetCapabilities()->GetDefaultColorFormat(),
1103  PixelFormat::kB10G10R10A10XR);
1104 }

References impeller::kB10G10R10A10XR.

◆ TEST_P() [179/454]

impeller::testing::TEST_P ( AiksTest  ,
FramebufferAdvancedBlendCoverage   
)

Definition at line 751 of file aiks_dl_blend_unittests.cc.

751  {
752  auto texture = CreateTextureForFixture("airplane.jpg",
753  /*enable_mipmapping=*/true);
754 
755  // Draw with an advanced blend that can use FramebufferBlendContents and
756  // verify that the scale transform is correctly applied to the image.
757  DisplayListBuilder builder;
758 
759  DlPaint paint;
760  paint.setColor(
761  DlColor::RGBA(169.0f / 255.0f, 169.0f / 255.0f, 169.0f / 255.0f, 1.0f));
762  builder.DrawPaint(paint);
763  builder.Scale(0.4, 0.4);
764 
765  DlPaint image_paint;
766  image_paint.setBlendMode(DlBlendMode::kMultiply);
767 
768  builder.DrawImage(DlImageImpeller::Make(texture), {20, 20},
769  DlImageSampling::kMipmapLinear, &image_paint);
770 
771  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
772 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [180/454]

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() [181/454]

impeller::testing::TEST_P ( AiksTest  ,
GaussianBlurAnimatedBackdrop   
)

Definition at line 749 of file aiks_dl_blur_unittests.cc.

749  {
750  // This test is for checking out how stable rendering is when content is
751  // translated underneath a blur. Animating under a blur can cause
752  // *shimmering* to happen as a result of pixel alignment.
753  // See also: https://github.com/flutter/flutter/issues/140193
754  auto boston =
755  CreateTextureForFixture("boston.jpg", /*enable_mipmapping=*/true);
756  ASSERT_TRUE(boston);
757  int64_t count = 0;
758  Scalar sigma = 20.0;
759  Scalar freq = 0.1;
760  Scalar amp = 50.0;
761  auto callback = [&]() -> sk_sp<DisplayList> {
762  if (AiksTest::ImGuiBegin("Controls", nullptr,
763  ImGuiWindowFlags_AlwaysAutoResize)) {
764  ImGui::SliderFloat("Sigma", &sigma, 0, 200);
765  ImGui::SliderFloat("Frequency", &freq, 0.01, 2.0);
766  ImGui::SliderFloat("Amplitude", &amp, 1, 100);
767  ImGui::End();
768  }
769 
770  DisplayListBuilder builder;
771  builder.Scale(GetContentScale().x, GetContentScale().y);
772  Scalar y = amp * sin(freq * 2.0 * M_PI * count / 60);
773  builder.DrawImage(
774  DlImageImpeller::Make(boston),
775  SkPoint::Make(1024 / 2 - boston->GetSize().width / 2,
776  (768 / 2 - boston->GetSize().height / 2) + y),
777  DlImageSampling::kMipmapLinear);
778  static PlaygroundPoint point_a(Point(100, 100), 20, Color::Red());
779  static PlaygroundPoint point_b(Point(900, 700), 20, Color::Red());
780  auto [handle_a, handle_b] = DrawPlaygroundLine(point_a, point_b);
781 
782  builder.ClipRect(
783  SkRect::MakeLTRB(handle_a.x, handle_a.y, handle_b.x, handle_b.y));
784  builder.ClipRect(SkRect::MakeLTRB(100, 100, 900, 700));
785 
786  DlPaint paint;
787  paint.setBlendMode(DlBlendMode::kSrc);
788 
789  auto backdrop_filter =
790  DlBlurImageFilter::Make(sigma, sigma, DlTileMode::kClamp);
791  builder.SaveLayer(nullptr, &paint, backdrop_filter.get());
792  count += 1;
793  return builder.Build();
794  };
795  ASSERT_TRUE(OpenPlaygroundHere(callback));
796 }

References impeller::DrawPlaygroundLine(), impeller::AiksPlayground::ImGuiBegin(), impeller::DlImageImpeller::Make(), and impeller::Color::Red().

◆ TEST_P() [182/454]

impeller::testing::TEST_P ( AiksTest  ,
GaussianBlurAtPeripheryHorizontal   
)

Definition at line 720 of file aiks_dl_blur_unittests.cc.

720  {
721  DisplayListBuilder builder;
722 
723  builder.Scale(GetContentScale().x, GetContentScale().y);
724  std::shared_ptr<Texture> boston = CreateTextureForFixture("boston.jpg");
725  builder.DrawImageRect(
726  DlImageImpeller::Make(boston),
727  SkRect::MakeXYWH(0, 0, boston->GetSize().width, boston->GetSize().height),
728  SkRect::MakeLTRB(0, 0, GetWindowSize().width, 100),
729  DlImageSampling::kNearestNeighbor);
730 
731  DlPaint paint;
732  paint.setColor(DlColor::kMagenta());
733 
734  SkRRect rrect = SkRRect::MakeRectXY(
735  SkRect::MakeLTRB(0, 110, GetWindowSize().width, 210), 10, 10);
736  builder.DrawRRect(rrect, paint);
737  builder.ClipRect(SkRect::MakeLTRB(0, 50, GetWindowSize().width, 150));
738 
739  DlPaint save_paint;
740  save_paint.setBlendMode(DlBlendMode::kSrc);
741 
742  auto backdrop_filter = DlBlurImageFilter::Make(20, 20, DlTileMode::kClamp);
743  builder.SaveLayer(nullptr, &save_paint, backdrop_filter.get());
744 
745  builder.Restore();
746  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
747 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [183/454]

impeller::testing::TEST_P ( AiksTest  ,
GaussianBlurAtPeripheryVertical   
)

Definition at line 692 of file aiks_dl_blur_unittests.cc.

692  {
693  DisplayListBuilder builder;
694 
695  DlPaint paint;
696  builder.Scale(GetContentScale().x, GetContentScale().y);
697 
698  paint.setColor(DlColor::kLimeGreen());
699  SkRRect rrect = SkRRect::MakeRectXY(
700  SkRect::MakeLTRB(0, 0, GetWindowSize().width, 100), 10, 10);
701  builder.DrawRRect(rrect, paint);
702 
703  paint.setColor(DlColor::kMagenta());
704  rrect = SkRRect::MakeRectXY(
705  SkRect::MakeLTRB(0, 110, GetWindowSize().width, 210), 10, 10);
706  builder.DrawRRect(rrect, paint);
707  builder.ClipRect(SkRect::MakeLTRB(100, 0, 200, GetWindowSize().height));
708 
709  DlPaint save_paint;
710  save_paint.setBlendMode(DlBlendMode::kSrc);
711 
712  auto backdrop_filter = DlBlurImageFilter::Make(20, 20, DlTileMode::kClamp);
713 
714  builder.SaveLayer(nullptr, &save_paint, backdrop_filter.get());
715  builder.Restore();
716 
717  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
718 }

◆ TEST_P() [184/454]

impeller::testing::TEST_P ( AiksTest  ,
GaussianBlurBackdropTinyMipMap   
)

Definition at line 1238 of file aiks_dl_blur_unittests.cc.

1238  {
1239  AiksContext renderer(GetContext(), nullptr);
1240  for (int32_t i = 1; i < 5; ++i) {
1241  DisplayListBuilder builder;
1242 
1243  ISize clip_size = ISize(i, i);
1244  builder.Save();
1245  builder.ClipRect(
1246  SkRect::MakeXYWH(400, 400, clip_size.width, clip_size.height));
1247 
1248  DlPaint paint;
1249  paint.setColor(DlColor::kGreen());
1250  auto blur_filter = DlBlurImageFilter::Make(0.1, 0.1, DlTileMode::kDecal);
1251  paint.setImageFilter(blur_filter);
1252 
1253  builder.DrawCircle({400, 400}, 200, paint);
1254  builder.Restore();
1255 
1256  auto image = DisplayListToTexture(builder.Build(), {1024, 768}, renderer);
1257  EXPECT_TRUE(image) << " length " << i;
1258  }
1259 }

References impeller::DisplayListToTexture(), impeller::TSize< T >::height, and impeller::TSize< T >::width.

◆ TEST_P() [185/454]

impeller::testing::TEST_P ( AiksTest  ,
GaussianBlurOneDimension   
)

Definition at line 996 of file aiks_dl_blur_unittests.cc.

996  {
997  DisplayListBuilder builder;
998 
999  builder.Scale(GetContentScale().x, GetContentScale().y);
1000  builder.Scale(0.5, 0.5);
1001 
1002  std::shared_ptr<Texture> boston = CreateTextureForFixture("boston.jpg");
1003  builder.DrawImage(DlImageImpeller::Make(boston), {100, 100}, {});
1004 
1005  DlPaint paint;
1006  paint.setBlendMode(DlBlendMode::kSrc);
1007 
1008  auto backdrop_filter = DlBlurImageFilter::Make(50, 0, DlTileMode::kClamp);
1009  builder.SaveLayer(nullptr, &paint, backdrop_filter.get());
1010  builder.Restore();
1011  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1012 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [186/454]

impeller::testing::TEST_P ( AiksTest  ,
GaussianBlurRotatedAndClipped   
)

Definition at line 1018 of file aiks_dl_blur_unittests.cc.

1018  {
1019  DisplayListBuilder builder;
1020 
1021  std::shared_ptr<Texture> boston = CreateTextureForFixture("boston.jpg");
1022  Rect bounds =
1023  Rect::MakeXYWH(0, 0, boston->GetSize().width, boston->GetSize().height);
1024 
1025  DlPaint paint;
1026  paint.setImageFilter(DlBlurImageFilter::Make(20, 20, DlTileMode::kDecal));
1027 
1028  Vector2 image_center = Vector2(bounds.GetSize() / 2);
1029  Vector2 clip_size = {150, 75};
1030  Vector2 center = Vector2(1024, 768) / 2;
1031  builder.Scale(GetContentScale().x, GetContentScale().y);
1032 
1033  auto clip_bounds =
1034  Rect::MakeLTRB(center.x, center.y, center.x, center.y).Expand(clip_size);
1035  builder.ClipRect(SkRect::MakeLTRB(clip_bounds.GetLeft(), clip_bounds.GetTop(),
1036  clip_bounds.GetRight(),
1037  clip_bounds.GetBottom()));
1038  builder.Translate(center.x, center.y);
1039  builder.Scale(0.6, 0.6);
1040  builder.Rotate(25);
1041 
1042  auto dst_rect = bounds.Shift(-image_center);
1043  builder.DrawImageRect(
1044  DlImageImpeller::Make(boston), /*src=*/
1045  SkRect::MakeLTRB(bounds.GetLeft(), bounds.GetTop(), bounds.GetRight(),
1046  bounds.GetBottom()),
1047  /*dst=*/
1048  SkRect::MakeLTRB(dst_rect.GetLeft(), dst_rect.GetTop(),
1049  dst_rect.GetRight(), dst_rect.GetBottom()),
1050  DlImageSampling::kMipmapLinear, &paint);
1051 
1052  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1053 }

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(), impeller::TPoint< T >::x, and impeller::TPoint< T >::y.

◆ TEST_P() [187/454]

impeller::testing::TEST_P ( AiksTest  ,
GaussianBlurRotatedAndClippedInteractive   
)

Definition at line 941 of file aiks_dl_blur_unittests.cc.

941  {
942  std::shared_ptr<Texture> boston = CreateTextureForFixture("boston.jpg");
943 
944  auto callback = [&]() -> sk_sp<DisplayList> {
945  const char* tile_mode_names[] = {"Clamp", "Repeat", "Mirror", "Decal"};
946  const DlTileMode tile_modes[] = {DlTileMode::kClamp, DlTileMode::kRepeat,
947  DlTileMode::kMirror, DlTileMode::kDecal};
948 
949  static float rotation = 0;
950  static float scale = 0.6;
951  static int selected_tile_mode = 3;
952 
953  if (AiksTest::ImGuiBegin("Controls", nullptr,
954  ImGuiWindowFlags_AlwaysAutoResize)) {
955  ImGui::SliderFloat("Rotation (degrees)", &rotation, -180, 180);
956  ImGui::SliderFloat("Scale", &scale, 0, 2.0);
957  ImGui::Combo("Tile mode", &selected_tile_mode, tile_mode_names,
958  sizeof(tile_mode_names) / sizeof(char*));
959  ImGui::End();
960  }
961 
962  DisplayListBuilder builder;
963  Rect bounds =
964  Rect::MakeXYWH(0, 0, boston->GetSize().width, boston->GetSize().height);
965  Vector2 image_center = Vector2(bounds.GetSize() / 2);
966  DlPaint paint;
967  paint.setImageFilter(
968  DlBlurImageFilter::Make(20, 20, tile_modes[selected_tile_mode]));
969 
970  static PlaygroundPoint point_a(Point(362, 309), 20, Color::Red());
971  static PlaygroundPoint point_b(Point(662, 459), 20, Color::Red());
972  auto [handle_a, handle_b] = DrawPlaygroundLine(point_a, point_b);
973  Vector2 center = Vector2(1024, 768) / 2;
974 
975  builder.Scale(GetContentScale().x, GetContentScale().y);
976  builder.ClipRect(
977  SkRect::MakeLTRB(handle_a.x, handle_a.y, handle_b.x, handle_b.y));
978  builder.Translate(center.x, center.y);
979  builder.Scale(scale, scale);
980  builder.Rotate(rotation);
981 
982  SkRect sk_bounds = SkRect::MakeLTRB(bounds.GetLeft(), bounds.GetTop(),
983  bounds.GetRight(), bounds.GetBottom());
984  Rect dest = bounds.Shift(-image_center);
985  SkRect sk_dst = SkRect::MakeLTRB(dest.GetLeft(), dest.GetTop(),
986  dest.GetRight(), dest.GetBottom());
987  builder.DrawImageRect(DlImageImpeller::Make(boston), /*src=*/sk_bounds,
988  /*dst=*/sk_dst, DlImageSampling::kNearestNeighbor,
989  &paint);
990  return builder.Build();
991  };
992 
993  ASSERT_TRUE(OpenPlaygroundHere(callback));
994 }

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(), impeller::TPoint< T >::x, and impeller::TPoint< T >::y.

◆ TEST_P() [188/454]

impeller::testing::TEST_P ( AiksTest  ,
GaussianBlurRotatedNonUniform   
)

Definition at line 1055 of file aiks_dl_blur_unittests.cc.

1055  {
1056  auto callback = [&]() -> sk_sp<DisplayList> {
1057  const char* tile_mode_names[] = {"Clamp", "Repeat", "Mirror", "Decal"};
1058  const DlTileMode tile_modes[] = {DlTileMode::kClamp, DlTileMode::kRepeat,
1059  DlTileMode::kMirror, DlTileMode::kDecal};
1060 
1061  static float rotation = 45;
1062  static float scale = 0.6;
1063  static int selected_tile_mode = 3;
1064 
1065  if (AiksTest::ImGuiBegin("Controls", nullptr,
1066  ImGuiWindowFlags_AlwaysAutoResize)) {
1067  ImGui::SliderFloat("Rotation (degrees)", &rotation, -180, 180);
1068  ImGui::SliderFloat("Scale", &scale, 0, 2.0);
1069  ImGui::Combo("Tile mode", &selected_tile_mode, tile_mode_names,
1070  sizeof(tile_mode_names) / sizeof(char*));
1071  ImGui::End();
1072  }
1073 
1074  DisplayListBuilder builder;
1075 
1076  DlPaint paint;
1077  paint.setColor(DlColor::kGreen());
1078  paint.setImageFilter(
1079  DlBlurImageFilter::Make(50, 0, tile_modes[selected_tile_mode]));
1080 
1081  Vector2 center = Vector2(1024, 768) / 2;
1082  builder.Scale(GetContentScale().x, GetContentScale().y);
1083  builder.Translate(center.x, center.y);
1084  builder.Scale(scale, scale);
1085  builder.Rotate(rotation);
1086 
1087  SkRRect rrect =
1088  SkRRect::MakeRectXY(SkRect::MakeXYWH(-100, -100, 200, 200), 10, 10);
1089  builder.DrawRRect(rrect, paint);
1090  return builder.Build();
1091  };
1092 
1093  ASSERT_TRUE(OpenPlaygroundHere(callback));
1094 }

References impeller::AiksPlayground::ImGuiBegin(), impeller::TPoint< T >::Rotate(), scale, impeller::TPoint< T >::x, and impeller::TPoint< T >::y.

◆ TEST_P() [189/454]

impeller::testing::TEST_P ( AiksTest  ,
GaussianBlurScaledAndClipped   
)

Definition at line 908 of file aiks_dl_blur_unittests.cc.

908  {
909  DisplayListBuilder builder;
910  std::shared_ptr<Texture> boston = CreateTextureForFixture("boston.jpg");
911  Rect bounds =
912  Rect::MakeXYWH(0, 0, boston->GetSize().width, boston->GetSize().height);
913  Vector2 image_center = Vector2(bounds.GetSize() / 2);
914 
915  DlPaint paint;
916  paint.setImageFilter(DlBlurImageFilter::Make(20, 20, DlTileMode::kDecal));
917 
918  Vector2 clip_size = {150, 75};
919  Vector2 center = Vector2(1024, 768) / 2;
920  builder.Scale(GetContentScale().x, GetContentScale().y);
921 
922  auto rect =
923  Rect::MakeLTRB(center.x, center.y, center.x, center.y).Expand(clip_size);
924  builder.ClipRect(SkRect::MakeLTRB(rect.GetLeft(), rect.GetTop(),
925  rect.GetRight(), rect.GetBottom()));
926  builder.Translate(center.x, center.y);
927  builder.Scale(0.6, 0.6);
928 
929  SkRect sk_bounds = SkRect::MakeLTRB(bounds.GetLeft(), bounds.GetTop(),
930  bounds.GetRight(), bounds.GetBottom());
931  Rect dest = bounds.Shift(-image_center);
932  SkRect sk_dst = SkRect::MakeLTRB(dest.GetLeft(), dest.GetTop(),
933  dest.GetRight(), dest.GetBottom());
934  builder.DrawImageRect(DlImageImpeller::Make(boston), /*src=*/sk_bounds,
935  /*dst=*/sk_dst, DlImageSampling::kNearestNeighbor,
936  &paint);
937 
938  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
939 }

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(), impeller::TPoint< T >::x, and impeller::TPoint< T >::y.

◆ TEST_P() [190/454]

impeller::testing::TEST_P ( AiksTest  ,
GaussianBlurSolidColorTinyMipMap   
)

Definition at line 1213 of file aiks_dl_blur_unittests.cc.

1213  {
1214  AiksContext renderer(GetContext(), nullptr);
1215 
1216  for (int32_t i = 1; i < 5; ++i) {
1217  DisplayListBuilder builder;
1218  Scalar fi = i;
1219  SkPath path;
1220  path.moveTo(100, 100);
1221  path.lineTo(100 + fi, 100 + fi);
1222 
1223  DlPaint paint;
1224  paint.setColor(DlColor::kChartreuse());
1225  auto blur_filter = DlBlurImageFilter::Make(0.1, 0.1, DlTileMode::kClamp);
1226  paint.setImageFilter(blur_filter);
1227 
1228  builder.DrawPath(path, paint);
1229 
1230  auto image = DisplayListToTexture(builder.Build(), {1024, 768}, renderer);
1231  EXPECT_TRUE(image) << " length " << i;
1232  }
1233 }

References impeller::DisplayListToTexture().

◆ TEST_P() [191/454]

impeller::testing::TEST_P ( AiksTest  ,
GaussianBlurStyleInner   
)

Definition at line 547 of file aiks_dl_blur_unittests.cc.

547  {
548  DisplayListBuilder builder;
549  builder.Scale(GetContentScale().x, GetContentScale().y);
550 
551  DlPaint paint;
552  paint.setColor(DlColor::RGBA(0.1, 0.1, 0.1, 1));
553  builder.DrawPaint(paint);
554 
555  paint.setColor(DlColor::kGreen());
556  paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kInner, 30));
557 
558  SkPath path;
559  path.moveTo(200, 200);
560  path.lineTo(300, 400);
561  path.lineTo(100, 400);
562  path.close();
563 
564  builder.DrawPath(path, paint);
565 
566  // Draw another thing to make sure the clip area is reset.
567  DlPaint red;
568  red.setColor(DlColor::kRed());
569  builder.DrawRect(SkRect::MakeXYWH(0, 0, 200, 200), red);
570 
571  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
572 }

◆ TEST_P() [192/454]

impeller::testing::TEST_P ( AiksTest  ,
GaussianBlurStyleInnerGradient   
)

Definition at line 798 of file aiks_dl_blur_unittests.cc.

798  {
799  DisplayListBuilder builder;
800 
801  builder.Scale(GetContentScale().x, GetContentScale().y);
802 
803  DlPaint paint;
804  paint.setColor(DlColor::RGBA(0.1, 0.1, 0.1, 1.0));
805  builder.DrawPaint(paint);
806 
807  std::vector<DlColor> colors = {DlColor::RGBA(0.9568, 0.2627, 0.2118, 1.0),
808  DlColor::RGBA(0.7568, 0.2627, 0.2118, 1.0)};
809  std::vector<Scalar> stops = {0.0, 1.0};
810 
811  paint = DlPaint{};
812  paint.setColorSource(DlColorSource::MakeLinear(
813  /*start_point=*/{0, 0},
814  /*end_point=*/{200, 200},
815  /*stop_count=*/colors.size(),
816  /*colors=*/colors.data(),
817  /*stops=*/stops.data(),
818  /*tile_mode=*/DlTileMode::kMirror));
819  paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kInner, 30));
820 
821  SkPath path;
822  path.moveTo(200, 200);
823  path.lineTo(300, 400);
824  path.lineTo(100, 400);
825  path.close();
826  builder.DrawPath(path, paint);
827 
828  // Draw another thing to make sure the clip area is reset.
829  DlPaint red;
830  red.setColor(DlColor::kRed());
831  builder.DrawRect(SkRect::MakeXYWH(0, 0, 200, 200), red);
832 
833  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
834 }

◆ TEST_P() [193/454]

impeller::testing::TEST_P ( AiksTest  ,
GaussianBlurStyleOuter   
)

Definition at line 574 of file aiks_dl_blur_unittests.cc.

574  {
575  DisplayListBuilder builder;
576  builder.Scale(GetContentScale().x, GetContentScale().y);
577 
578  DlPaint paint;
579  paint.setColor(DlColor::RGBA(0.1, 0.1, 0.1, 1.0));
580  builder.DrawPaint(paint);
581 
582  paint.setColor(DlColor::kGreen());
583  paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kOuter, 30));
584 
585  SkPath path;
586  path.moveTo(200, 200);
587  path.lineTo(300, 400);
588  path.lineTo(100, 400);
589  path.close();
590 
591  builder.DrawPath(path, paint);
592 
593  // Draw another thing to make sure the clip area is reset.
594  DlPaint red;
595  red.setColor(DlColor::kRed());
596  builder.DrawRect(SkRect::MakeXYWH(0, 0, 200, 200), red);
597 
598  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
599 }

◆ TEST_P() [194/454]

impeller::testing::TEST_P ( AiksTest  ,
GaussianBlurStyleOuterGradient   
)

Definition at line 872 of file aiks_dl_blur_unittests.cc.

872  {
873  DisplayListBuilder builder;
874  builder.Scale(GetContentScale().x, GetContentScale().y);
875 
876  DlPaint paint;
877  paint.setColor(DlColor::RGBA(0.1, 0.1, 0.1, 1.0));
878  builder.DrawPaint(paint);
879 
880  std::vector<DlColor> colors = {DlColor::RGBA(0.9568, 0.2627, 0.2118, 1.0),
881  DlColor::RGBA(0.7568, 0.2627, 0.2118, 1.0)};
882  std::vector<Scalar> stops = {0.0, 1.0};
883 
884  paint = DlPaint{};
885  paint.setColorSource(DlColorSource::MakeLinear(
886  /*start_point=*/{0, 0},
887  /*end_point=*/{200, 200},
888  /*stop_count=*/colors.size(),
889  /*colors=*/colors.data(),
890  /*stops=*/stops.data(),
891  /*tile_mode=*/DlTileMode::kMirror));
892  paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kOuter, 30));
893 
894  SkPath path;
895  path.moveTo(200, 200);
896  path.lineTo(300, 400);
897  path.lineTo(100, 400);
898  path.close();
899  builder.DrawPath(path, paint);
900 
901  // Draw another thing to make sure the clip area is reset.
902  DlPaint red;
903  red.setColor(DlColor::kRed());
904  builder.DrawRect(SkRect::MakeXYWH(0, 0, 200, 200), red);
905  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
906 }

◆ TEST_P() [195/454]

impeller::testing::TEST_P ( AiksTest  ,
GaussianBlurStyleSolid   
)

Definition at line 601 of file aiks_dl_blur_unittests.cc.

601  {
602  DisplayListBuilder builder;
603  builder.Scale(GetContentScale().x, GetContentScale().y);
604 
605  DlPaint paint;
606  paint.setColor(DlColor::RGBA(0.1, 0.1, 0.1, 1.0));
607  builder.DrawPaint(paint);
608 
609  paint.setColor(DlColor::kGreen());
610  paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kSolid, 30));
611 
612  SkPath path;
613  path.moveTo(200, 200);
614  path.lineTo(300, 400);
615  path.lineTo(100, 400);
616  path.close();
617 
618  builder.DrawPath(path, paint);
619 
620  // Draw another thing to make sure the clip area is reset.
621  DlPaint red;
622  red.setColor(DlColor::kRed());
623  builder.DrawRect(SkRect::MakeXYWH(0, 0, 200, 200), red);
624 
625  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
626 }

◆ TEST_P() [196/454]

impeller::testing::TEST_P ( AiksTest  ,
GaussianBlurStyleSolidGradient   
)

Definition at line 836 of file aiks_dl_blur_unittests.cc.

836  {
837  DisplayListBuilder builder;
838  builder.Scale(GetContentScale().x, GetContentScale().y);
839 
840  DlPaint paint;
841  paint.setColor(DlColor::RGBA(0.1, 0.1, 0.1, 1.0));
842  builder.DrawPaint(paint);
843 
844  std::vector<DlColor> colors = {DlColor::RGBA(0.9568, 0.2627, 0.2118, 1.0),
845  DlColor::RGBA(0.7568, 0.2627, 0.2118, 1.0)};
846  std::vector<Scalar> stops = {0.0, 1.0};
847 
848  paint = DlPaint{};
849  paint.setColorSource(DlColorSource::MakeLinear(
850  /*start_point=*/{0, 0},
851  /*end_point=*/{200, 200},
852  /*stop_count=*/colors.size(),
853  /*colors=*/colors.data(),
854  /*stops=*/stops.data(),
855  /*tile_mode=*/DlTileMode::kMirror));
856  paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kSolid, 30));
857 
858  SkPath path;
859  path.moveTo(200, 200);
860  path.lineTo(300, 400);
861  path.lineTo(100, 400);
862  path.close();
863  builder.DrawPath(path, paint);
864 
865  // Draw another thing to make sure the clip area is reset.
866  DlPaint red;
867  red.setColor(DlColor::kRed());
868  builder.DrawRect(SkRect::MakeXYWH(0, 0, 200, 200), red);
869  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
870 }

◆ TEST_P() [197/454]

impeller::testing::TEST_P ( AiksTest  ,
GaussianBlurWithoutDecalSupport   
)

Definition at line 1160 of file aiks_dl_blur_unittests.cc.

1160  {
1161  if (GetParam() != PlaygroundBackend::kMetal) {
1162  GTEST_SKIP()
1163  << "This backend doesn't yet support setting device capabilities.";
1164  }
1165  if (!WillRenderSomething()) {
1166  // Sometimes these tests are run without playgrounds enabled which is
1167  // pointless for this test since we are asserting that
1168  // `SupportsDecalSamplerAddressMode` is called.
1169  GTEST_SKIP() << "This test requires playgrounds.";
1170  }
1171 
1172  std::shared_ptr<const Capabilities> old_capabilities =
1173  GetContext()->GetCapabilities();
1174  auto mock_capabilities = std::make_shared<MockCapabilities>();
1175  EXPECT_CALL(*mock_capabilities, SupportsDecalSamplerAddressMode())
1176  .Times(::testing::AtLeast(1))
1177  .WillRepeatedly(::testing::Return(false));
1178  FLT_FORWARD(mock_capabilities, old_capabilities, GetDefaultColorFormat);
1179  FLT_FORWARD(mock_capabilities, old_capabilities, GetDefaultStencilFormat);
1180  FLT_FORWARD(mock_capabilities, old_capabilities,
1181  GetDefaultDepthStencilFormat);
1182  FLT_FORWARD(mock_capabilities, old_capabilities, SupportsOffscreenMSAA);
1183  FLT_FORWARD(mock_capabilities, old_capabilities,
1184  SupportsImplicitResolvingMSAA);
1185  FLT_FORWARD(mock_capabilities, old_capabilities, SupportsReadFromResolve);
1186  FLT_FORWARD(mock_capabilities, old_capabilities, SupportsFramebufferFetch);
1187  FLT_FORWARD(mock_capabilities, old_capabilities, SupportsSSBO);
1188  FLT_FORWARD(mock_capabilities, old_capabilities, SupportsCompute);
1189  FLT_FORWARD(mock_capabilities, old_capabilities,
1190  SupportsTextureToTextureBlits);
1191  FLT_FORWARD(mock_capabilities, old_capabilities, GetDefaultGlyphAtlasFormat);
1192  FLT_FORWARD(mock_capabilities, old_capabilities, SupportsTriangleFan);
1193  ASSERT_TRUE(SetCapabilities(mock_capabilities).ok());
1194 
1195  auto texture = DlImageImpeller::Make(CreateTextureForFixture("boston.jpg"));
1196 
1197  DisplayListBuilder builder;
1198  builder.Scale(GetContentScale().x * 0.5, GetContentScale().y * 0.5);
1199 
1200  DlPaint paint;
1201  paint.setColor(DlColor::kBlack());
1202  builder.DrawPaint(paint);
1203 
1204  auto blur_filter = DlBlurImageFilter::Make(20, 20, DlTileMode::kDecal);
1205  paint.setImageFilter(blur_filter);
1206  builder.DrawImage(texture, SkPoint::Make(200, 200), {}, &paint);
1207  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1208 }

References impeller::kMetal, and impeller::DlImageImpeller::Make().

◆ TEST_P() [198/454]

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 }

References DoGradientOvalStrokeMaskBlur().

◆ TEST_P() [199/454]

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() [200/454]

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() [201/454]

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() [202/454]

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() [203/454]

impeller::testing::TEST_P ( AiksTest  ,
GradientStrokesRenderCorrectly   
)

Definition at line 624 of file aiks_dl_gradient_unittests.cc.

624  {
625  // Compare with https://fiddle.skia.org/c/027392122bec8ac2b5d5de00a4b9bbe2
626  auto callback = [&]() -> sk_sp<DisplayList> {
627  static float scale = 3;
628  static bool add_circle_clip = true;
629  const char* tile_mode_names[] = {"Clamp", "Repeat", "Mirror", "Decal"};
630  const DlTileMode tile_modes[] = {DlTileMode::kClamp, DlTileMode::kRepeat,
631  DlTileMode::kMirror, DlTileMode::kDecal};
632  static int selected_tile_mode = 0;
633  static float alpha = 1;
634 
635  if (AiksTest::ImGuiBegin("Controls", nullptr,
636  ImGuiWindowFlags_AlwaysAutoResize)) {
637  ImGui::SliderFloat("Scale", &scale, 0, 6);
638  ImGui::Checkbox("Circle clip", &add_circle_clip);
639  ImGui::SliderFloat("Alpha", &alpha, 0, 1);
640  ImGui::Combo("Tile mode", &selected_tile_mode, tile_mode_names,
641  sizeof(tile_mode_names) / sizeof(char*));
642  ImGui::End();
643  }
644 
645  DisplayListBuilder builder;
646  builder.Scale(GetContentScale().x, GetContentScale().y);
647  DlPaint paint;
648  paint.setColor(DlColor::kWhite());
649  builder.DrawPaint(paint);
650 
651  paint.setDrawStyle(DlDrawStyle::kStroke);
652  paint.setColor(DlColor::kWhite().withAlpha(alpha * 255));
653  paint.setStrokeWidth(10);
654  auto tile_mode = tile_modes[selected_tile_mode];
655 
656  std::vector<DlColor> colors = {
657  DlColor(Color{0.9568, 0.2627, 0.2118, 1.0}.ToARGB()),
658  DlColor(Color{0.1294, 0.5882, 0.9529, 1.0}.ToARGB())};
659  std::vector<Scalar> stops = {0.0, 1.0};
660 
661  paint.setColorSource(DlColorSource::MakeLinear({0, 0}, {50, 50},
662  stops.size(), colors.data(),
663  stops.data(), tile_mode));
664 
665  SkPath path;
666  path.moveTo(20, 20);
667  path.quadTo({60, 20}, {60, 60});
668  path.close();
669  path.moveTo(60, 20);
670  path.quadTo({60, 60}, {20, 60});
671 
672  builder.Scale(scale, scale);
673 
674  if (add_circle_clip) {
675  static PlaygroundPoint circle_clip_point_a(Point(60, 300), 20,
676  Color::Red());
677  static PlaygroundPoint circle_clip_point_b(Point(600, 300), 20,
678  Color::Red());
679  auto [handle_a, handle_b] =
680  DrawPlaygroundLine(circle_clip_point_a, circle_clip_point_b);
681 
682  SkMatrix screen_to_canvas;
683  if (!builder.GetTransform().invert(&screen_to_canvas)) {
684  return nullptr;
685  }
686  Matrix ip_matrix = ToMatrix(screen_to_canvas);
687  Point point_a = ip_matrix * handle_a * GetContentScale();
688  Point point_b = ip_matrix * handle_b * GetContentScale();
689 
690  Point middle = (point_a + point_b) / 2;
691  auto radius = point_a.GetDistance(middle);
692  SkPath circle;
693  circle.addCircle(middle.x, middle.y, radius);
694  builder.ClipPath(circle);
695  }
696 
697  for (auto join :
698  {DlStrokeJoin::kBevel, DlStrokeJoin::kRound, DlStrokeJoin::kMiter}) {
699  paint.setStrokeJoin(join);
700  for (auto cap :
701  {DlStrokeCap::kButt, DlStrokeCap::kSquare, DlStrokeCap::kRound}) {
702  paint.setStrokeCap(cap);
703  builder.DrawPath(path, paint);
704  builder.Translate(80, 0);
705  }
706  builder.Translate(-240, 60);
707  }
708 
709  return builder.Build();
710  };
711 
712  ASSERT_TRUE(OpenPlaygroundHere(callback));
713 }

References impeller::DrawPlaygroundLine(), impeller::TPoint< T >::GetDistance(), scale, impeller::Color::ToARGB(), impeller::skia_conversions::ToMatrix(), impeller::TPoint< T >::x, and impeller::TPoint< T >::y.

◆ TEST_P() [204/454]

impeller::testing::TEST_P ( AiksTest  ,
ImageColorSourceEffectTransform   
)

Definition at line 887 of file aiks_dl_basic_unittests.cc.

887  {
888  // Compare with https://fiddle.skia.org/c/6cdc5aefb291fda3833b806ca347a885
889 
890  DisplayListBuilder builder;
891  auto texture = DlImageImpeller::Make(CreateTextureForFixture("monkey.png"));
892 
893  DlPaint paint;
894  paint.setColor(DlColor::kWhite());
895  builder.DrawPaint(paint);
896 
897  // Translation
898  {
899  SkMatrix matrix = SkMatrix::Translate(50, 50);
900  DlPaint paint;
901  paint.setColorSource(std::make_shared<DlImageColorSource>(
902  texture, DlTileMode::kRepeat, DlTileMode::kRepeat,
903  DlImageSampling::kNearestNeighbor, &matrix));
904 
905  builder.DrawRect(SkRect::MakeLTRB(0, 0, 100, 100), paint);
906  }
907 
908  // Rotation/skew
909  {
910  builder.Save();
911  builder.Rotate(45);
912  DlPaint paint;
913 
914  Matrix impeller_matrix(1, -1, 0, 0, //
915  1, 1, 0, 0, //
916  0, 0, 1, 0, //
917  0, 0, 0, 1);
918  SkMatrix matrix = SkM44::ColMajor(impeller_matrix.m).asM33();
919  paint.setColorSource(std::make_shared<DlImageColorSource>(
920  texture, DlTileMode::kRepeat, DlTileMode::kRepeat,
921  DlImageSampling::kNearestNeighbor, &matrix));
922  builder.DrawRect(SkRect::MakeLTRB(100, 0, 200, 100), paint);
923  builder.Restore();
924  }
925 
926  // Scale
927  {
928  builder.Translate(100, 0);
929  builder.Scale(100, 100);
930  DlPaint paint;
931 
932  SkMatrix matrix = SkMatrix::Scale(0.005, 0.005);
933  paint.setColorSource(std::make_shared<DlImageColorSource>(
934  texture, DlTileMode::kRepeat, DlTileMode::kRepeat,
935  DlImageSampling::kNearestNeighbor, &matrix));
936 
937  builder.DrawRect(SkRect::MakeLTRB(0, 0, 1, 1), paint);
938  }
939 
940  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
941 }

References impeller::Matrix::m, and impeller::DlImageImpeller::Make().

◆ TEST_P() [205/454]

impeller::testing::TEST_P ( AiksTest  ,
ImageFilteredSaveLayerWithUnboundedContents   
)

Definition at line 651 of file aiks_dl_unittests.cc.

651  {
652  DisplayListBuilder builder;
653  builder.Scale(GetContentScale().x, GetContentScale().y);
654 
655  auto test = [&builder](const std::shared_ptr<const DlImageFilter>& filter) {
656  auto DrawLine = [&builder](const SkPoint& p0, const SkPoint& p1,
657  const DlPaint& p) {
658  DlPaint paint = p;
659  paint.setDrawStyle(DlDrawStyle::kStroke);
660  builder.DrawPath(SkPath::Line(p0, p1), paint);
661  };
662  // Registration marks for the edge of the SaveLayer
663  DlPaint paint;
664  paint.setColor(DlColor::kWhite());
665  DrawLine(SkPoint::Make(75, 100), SkPoint::Make(225, 100), paint);
666  DrawLine(SkPoint::Make(75, 200), SkPoint::Make(225, 200), paint);
667  DrawLine(SkPoint::Make(100, 75), SkPoint::Make(100, 225), paint);
668  DrawLine(SkPoint::Make(200, 75), SkPoint::Make(200, 225), paint);
669 
670  DlPaint save_paint;
671  save_paint.setImageFilter(filter);
672  SkRect bounds = SkRect::MakeLTRB(100, 100, 200, 200);
673  builder.SaveLayer(&bounds, &save_paint);
674 
675  {
676  // DrawPaint to verify correct behavior when the contents are unbounded.
677  DlPaint paint;
678  paint.setColor(DlColor::kYellow());
679  builder.DrawPaint(paint);
680 
681  // Contrasting rectangle to see interior blurring
682  paint.setColor(DlColor::kBlue());
683  builder.DrawRect(SkRect::MakeLTRB(125, 125, 175, 175), paint);
684  }
685  builder.Restore();
686  };
687 
688  test(std::make_shared<DlBlurImageFilter>(10.0, 10.0, DlTileMode::kDecal));
689 
690  builder.Translate(200.0, 0.0);
691 
692  test(std::make_shared<DlDilateImageFilter>(10.0, 10.0));
693 
694  builder.Translate(200.0, 0.0);
695 
696  test(std::make_shared<DlErodeImageFilter>(10.0, 10.0));
697 
698  builder.Translate(-400.0, 200.0);
699 
700  SkMatrix sk_matrix = SkMatrix::RotateDeg(10);
701 
702  auto rotate_filter = std::make_shared<DlMatrixImageFilter>(
703  sk_matrix, DlImageSampling::kLinear);
704  test(rotate_filter);
705 
706  builder.Translate(200.0, 0.0);
707 
708  const float m[20] = {
709  0, 1, 0, 0, 0, //
710  0, 0, 1, 0, 0, //
711  1, 0, 0, 0, 0, //
712  0, 0, 0, 1, 0 //
713  };
714  auto rgb_swap_filter = std::make_shared<DlColorFilterImageFilter>(
715  std::make_shared<DlMatrixColorFilter>(m));
716  test(rgb_swap_filter);
717 
718  builder.Translate(200.0, 0.0);
719 
720  test(DlComposeImageFilter::Make(rotate_filter, rgb_swap_filter));
721 
722  builder.Translate(-400.0, 200.0);
723 
724  test(std::make_shared<DlLocalMatrixImageFilter>(
725  SkMatrix::Translate(25.0, 25.0), rotate_filter));
726 
727  builder.Translate(200.0, 0.0);
728 
729  test(std::make_shared<DlLocalMatrixImageFilter>(
730  SkMatrix::Translate(25.0, 25.0), rgb_swap_filter));
731 
732  builder.Translate(200.0, 0.0);
733 
734  test(std::make_shared<DlLocalMatrixImageFilter>(
735  SkMatrix::Translate(25.0, 25.0),
736  DlComposeImageFilter::Make(rotate_filter, rgb_swap_filter)));
737 
738  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
739 }

◆ TEST_P() [206/454]

impeller::testing::TEST_P ( AiksTest  ,
ImageFilteredUnboundedSaveLayerWithUnboundedContents   
)

Definition at line 216 of file aiks_dl_unittests.cc.

216  {
217  DisplayListBuilder builder(GetCullRect(GetWindowSize()));
218  builder.Scale(GetContentScale().x, GetContentScale().y);
219 
220  DlPaint save_paint;
221  save_paint.setImageFilter(
222  DlBlurImageFilter::Make(10.0, 10.0, DlTileMode::kDecal));
223  builder.SaveLayer(nullptr, &save_paint);
224 
225  {
226  // DrawPaint to verify correct behavior when the contents are unbounded.
227  DlPaint draw_paint;
228  draw_paint.setColor(DlColor::kYellow());
229  builder.DrawPaint(draw_paint);
230 
231  // Contrasting rectangle to see interior blurring
232  DlPaint draw_rect;
233  draw_rect.setColor(DlColor::kBlue());
234  builder.DrawRect(SkRect::MakeLTRB(125, 125, 175, 175), draw_rect);
235  }
236  builder.Restore();
237 
238  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
239 }

◆ TEST_P() [207/454]

impeller::testing::TEST_P ( AiksTest  ,
LinearToSrgbFilterSubpassCollapseOptimization   
)

Definition at line 102 of file aiks_dl_unittests.cc.

102  {
103  DisplayListBuilder builder(GetCullRect(GetWindowSize()));
104 
105  DlPaint paint;
106  paint.setColorFilter(DlLinearToSrgbGammaColorFilter::kInstance);
107  builder.SaveLayer(nullptr, &paint);
108 
109  builder.Translate(500, 300);
110  builder.Rotate(120); // 120 deg.
111 
112  DlPaint draw_paint;
113  draw_paint.setColor(DlColor::kBlue());
114  builder.DrawRect(SkRect::MakeXYWH(100, 100, 200, 200), draw_paint);
115 
116  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
117 }

◆ TEST_P() [208/454]

impeller::testing::TEST_P ( AiksTest  ,
MaskBlurDoesntStretchContents   
)

Definition at line 657 of file aiks_dl_blur_unittests.cc.

657  {
658  Scalar sigma = 70;
659  auto callback = [&]() -> sk_sp<DisplayList> {
660  if (AiksTest::ImGuiBegin("Controls", nullptr,
661  ImGuiWindowFlags_AlwaysAutoResize)) {
662  ImGui::SliderFloat("Sigma", &sigma, 0, 500);
663  ImGui::End();
664  }
665 
666  DisplayListBuilder builder;
667  builder.Scale(GetContentScale().x, GetContentScale().y);
668 
669  DlPaint paint;
670  paint.setColor(DlColor::RGBA(0.1, 0.1, 0.1, 1.0));
671  builder.DrawPaint(paint);
672 
673  std::shared_ptr<Texture> boston = CreateTextureForFixture("boston.jpg");
674 
675  builder.Transform(SkMatrix::Translate(100, 100) *
676  SkMatrix::Scale(0.5, 0.5));
677 
678  paint.setColorSource(std::make_shared<DlImageColorSource>(
679  DlImageImpeller::Make(boston), DlTileMode::kRepeat, DlTileMode::kRepeat,
680  DlImageSampling::kMipmapLinear));
681  paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kNormal, sigma));
682 
683  builder.DrawRect(SkRect::MakeXYWH(0, 0, boston->GetSize().width,
684  boston->GetSize().height),
685  paint);
686 
687  return builder.Build();
688  };
689  ASSERT_TRUE(OpenPlaygroundHere(callback));
690 }

References impeller::AiksPlayground::ImGuiBegin(), and impeller::DlImageImpeller::Make().

◆ TEST_P() [209/454]

impeller::testing::TEST_P ( AiksTest  ,
MaskBlurTexture   
)

Definition at line 628 of file aiks_dl_blur_unittests.cc.

628  {
629  Scalar sigma = 30;
630  auto callback = [&]() -> sk_sp<DisplayList> {
631  if (AiksTest::ImGuiBegin("Controls", nullptr,
632  ImGuiWindowFlags_AlwaysAutoResize)) {
633  ImGui::SliderFloat("Sigma", &sigma, 0, 500);
634  ImGui::End();
635  }
636 
637  DisplayListBuilder builder;
638  builder.Scale(GetContentScale().x, GetContentScale().y);
639 
640  DlPaint paint;
641  paint.setColor(DlColor::kGreen());
642  paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kNormal, sigma));
643 
644  builder.DrawImage(
645  DlImageImpeller::Make(CreateTextureForFixture("boston.jpg")),
646  {200, 200}, DlImageSampling::kNearestNeighbor, &paint);
647 
648  DlPaint red;
649  red.setColor(DlColor::kRed());
650  builder.DrawRect(SkRect::MakeXYWH(0, 0, 200, 200), red);
651 
652  return builder.Build();
653  };
654  ASSERT_TRUE(OpenPlaygroundHere(callback));
655 }

References impeller::AiksPlayground::ImGuiBegin(), and impeller::DlImageImpeller::Make().

◆ TEST_P() [210/454]

impeller::testing::TEST_P ( AiksTest  ,
MaskBlurWithZeroSigmaIsSkipped   
)

Definition at line 381 of file aiks_dl_blur_unittests.cc.

381  {
382  DisplayListBuilder builder;
383 
384  DlPaint paint;
385  paint.setColor(DlColor::kBlue());
386  paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kNormal, 0));
387 
388  builder.DrawCircle({300, 300}, 200, paint);
389  builder.DrawRect(SkRect::MakeLTRB(100, 300, 500, 600), paint);
390 
391  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
392 }

◆ TEST_P() [211/454]

impeller::testing::TEST_P ( AiksTest  ,
MassiveScalingMatrixImageFilter   
)

Definition at line 1515 of file aiks_dl_basic_unittests.cc.

1515  {
1516  if (GetBackend() == PlaygroundBackend::kVulkan) {
1517  GTEST_SKIP() << "Swiftshader is running out of memory on this example.";
1518  }
1519  DisplayListBuilder builder(SkRect::MakeSize(SkSize::Make(1000, 1000)));
1520 
1521  auto filter = DlMatrixImageFilter::Make(SkMatrix::Scale(0.001, 0.001),
1522  DlImageSampling::kLinear);
1523 
1524  DlPaint paint;
1525  paint.setImageFilter(filter);
1526  builder.SaveLayer(nullptr, &paint);
1527  {
1528  DlPaint paint;
1529  paint.setColor(DlColor::kRed());
1530  builder.DrawRect(SkRect::MakeLTRB(0, 0, 100000, 100000), paint);
1531  }
1532  builder.Restore();
1533 
1534  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1535 }

References impeller::kVulkan.

◆ TEST_P() [212/454]

impeller::testing::TEST_P ( AiksTest  ,
MatrixBackdropFilter   
)

Definition at line 741 of file aiks_dl_unittests.cc.

741  {
742  DisplayListBuilder builder;
743 
744  DlPaint paint;
745  paint.setColor(DlColor::kBlack());
746  builder.DrawPaint(paint);
747  builder.SaveLayer(nullptr, nullptr);
748  {
749  DlPaint paint;
750  paint.setColor(DlColor::kGreen().withAlpha(0.5 * 255));
751  paint.setBlendMode(DlBlendMode::kPlus);
752 
753  DlPaint rect_paint;
754  rect_paint.setColor(DlColor::kRed());
755  rect_paint.setStrokeWidth(4);
756  rect_paint.setDrawStyle(DlDrawStyle::kStroke);
757  builder.DrawRect(SkRect::MakeLTRB(0, 0, 300, 300), rect_paint);
758  builder.DrawCircle(SkPoint::Make(200, 200), 100, paint);
759  // Should render a second circle, centered on the bottom-right-most edge of
760  // the circle.
761  SkMatrix matrix = SkMatrix::Translate((100 + 100 * k1OverSqrt2),
762  (100 + 100 * k1OverSqrt2)) *
763  SkMatrix::Scale(0.5, 0.5) *
764  SkMatrix::Translate(-100, -100);
765  auto backdrop_filter =
766  DlMatrixImageFilter::Make(matrix, DlImageSampling::kLinear);
767  builder.SaveLayer(nullptr, nullptr, backdrop_filter.get());
768  builder.Restore();
769  }
770  builder.Restore();
771 
772  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
773 }

References impeller::k1OverSqrt2.

◆ TEST_P() [213/454]

impeller::testing::TEST_P ( AiksTest  ,
MatrixImageFilterDoesntCullWhenScaledAndTranslatedFromOffscreen   
)

Definition at line 993 of file aiks_dl_basic_unittests.cc.

994  {
995  DisplayListBuilder builder;
996  builder.Scale(GetContentScale().x, GetContentScale().y);
997  builder.Translate(100, 100);
998  // Draw a circle in a SaveLayer at -300, but move it back on-screen with a
999  // +300 translation applied by a SaveLayer image filter.
1000 
1001  DlPaint paint;
1002  paint.setImageFilter(DlMatrixImageFilter::Make(
1003  SkMatrix::Translate(300, 0) * SkMatrix::Scale(2, 2),
1004  DlImageSampling::kNearestNeighbor));
1005  builder.SaveLayer(nullptr, &paint);
1006 
1007  DlPaint circle_paint;
1008  circle_paint.setColor(DlColor::kGreen());
1009  builder.DrawCircle({-150, 0}, 50, circle_paint);
1010  builder.Restore();
1011 
1012  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1013 }

◆ TEST_P() [214/454]

impeller::testing::TEST_P ( AiksTest  ,
MatrixImageFilterDoesntCullWhenTranslatedFromOffscreen   
)

Definition at line 972 of file aiks_dl_basic_unittests.cc.

972  {
973  DisplayListBuilder builder;
974  builder.Scale(GetContentScale().x, GetContentScale().y);
975  builder.Translate(100, 100);
976  // Draw a circle in a SaveLayer at -300, but move it back on-screen with a
977  // +300 translation applied by a SaveLayer image filter.
978  DlPaint paint;
979  SkMatrix translate = SkMatrix::Translate(300, 0);
980  paint.setImageFilter(
981  DlMatrixImageFilter::Make(translate, DlImageSampling::kLinear));
982  builder.SaveLayer(nullptr, &paint);
983 
984  DlPaint circle_paint;
985  circle_paint.setColor(DlColor::kGreen());
986  builder.DrawCircle({-300, 0}, 100, circle_paint);
987  builder.Restore();
988 
989  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
990 }

◆ TEST_P() [215/454]

impeller::testing::TEST_P ( AiksTest  ,
MatrixImageFilterMagnify   
)

Definition at line 620 of file aiks_dl_unittests.cc.

620  {
621  Scalar scale = 2.0;
622  auto callback = [&]() -> sk_sp<DisplayList> {
623  if (AiksTest::ImGuiBegin("Controls", nullptr,
624  ImGuiWindowFlags_AlwaysAutoResize)) {
625  ImGui::SliderFloat("Scale", &scale, 1, 2);
626  ImGui::End();
627  }
628  DisplayListBuilder builder;
629  builder.Scale(GetContentScale().x, GetContentScale().y);
630  auto image = DlImageImpeller::Make(CreateTextureForFixture("airplane.jpg"));
631 
632  builder.Translate(600, -200);
633 
634  SkMatrix matrix = SkMatrix::Scale(scale, scale);
635  DlPaint paint;
636  paint.setImageFilter(
637  DlMatrixImageFilter::Make(matrix, DlImageSampling::kLinear));
638  builder.SaveLayer(nullptr, &paint);
639 
640  DlPaint rect_paint;
641  rect_paint.setAlpha(0.5 * 255);
642  builder.DrawImage(image, {0, 0}, DlImageSampling::kLinear, &rect_paint);
643  builder.Restore();
644 
645  return builder.Build();
646  };
647 
648  ASSERT_TRUE(OpenPlaygroundHere(callback));
649 }

References impeller::AiksPlayground::ImGuiBegin(), impeller::DlImageImpeller::Make(), and scale.

◆ TEST_P() [216/454]

impeller::testing::TEST_P ( AiksTest  ,
MatrixSaveLayerFilter   
)

Definition at line 775 of file aiks_dl_unittests.cc.

775  {
776  DisplayListBuilder builder;
777 
778  DlPaint paint;
779  paint.setColor(DlColor::kBlack());
780  builder.DrawPaint(paint);
781  builder.SaveLayer(nullptr, nullptr);
782  {
783  paint.setColor(DlColor::kGreen().withAlpha(255 * 0.5));
784  paint.setBlendMode(DlBlendMode::kPlus);
785  builder.DrawCircle({200, 200}, 100, paint);
786  // Should render a second circle, centered on the bottom-right-most edge of
787  // the circle.
788 
789  SkMatrix matrix = SkMatrix::Translate((200 + 100 * k1OverSqrt2),
790  (200 + 100 * k1OverSqrt2)) *
791  SkMatrix::Scale(0.5, 0.5) *
792  SkMatrix::Translate(-200, -200);
793  DlPaint save_paint;
794  save_paint.setImageFilter(
795  DlMatrixImageFilter::Make(matrix, DlImageSampling::kLinear));
796 
797  builder.SaveLayer(nullptr, &save_paint);
798 
799  DlPaint circle_paint;
800  circle_paint.setColor(DlColor::kGreen().withAlpha(255 * 0.5));
801  circle_paint.setBlendMode(DlBlendMode::kPlus);
802  builder.DrawCircle({200, 200}, 100, circle_paint);
803  builder.Restore();
804  }
805  builder.Restore();
806 
807  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
808 }

References impeller::k1OverSqrt2.

◆ TEST_P() [217/454]

impeller::testing::TEST_P ( AiksTest  ,
MipmapGenerationWorksCorrectly   
)

Definition at line 472 of file aiks_dl_unittests.cc.

472  {
473  TextureDescriptor texture_descriptor;
474  texture_descriptor.size = ISize{1024, 1024};
475  texture_descriptor.format = PixelFormat::kR8G8B8A8UNormInt;
476  texture_descriptor.storage_mode = StorageMode::kHostVisible;
477  texture_descriptor.mip_count = texture_descriptor.size.MipCount();
478 
479  std::vector<uint8_t> bytes(4194304);
480  bool alternate = false;
481  for (auto i = 0u; i < 4194304; i += 4) {
482  if (alternate) {
483  bytes[i] = 255;
484  bytes[i + 1] = 0;
485  bytes[i + 2] = 0;
486  bytes[i + 3] = 255;
487  } else {
488  bytes[i] = 0;
489  bytes[i + 1] = 255;
490  bytes[i + 2] = 0;
491  bytes[i + 3] = 255;
492  }
493  alternate = !alternate;
494  }
495 
496  ASSERT_EQ(texture_descriptor.GetByteSizeOfBaseMipLevel(), bytes.size());
497  auto mapping = std::make_shared<fml::NonOwnedMapping>(
498  bytes.data(), // data
499  texture_descriptor.GetByteSizeOfBaseMipLevel() // size
500  );
501  auto texture =
502  GetContext()->GetResourceAllocator()->CreateTexture(texture_descriptor);
503 
504  auto device_buffer =
505  GetContext()->GetResourceAllocator()->CreateBufferWithCopy(*mapping);
506  auto command_buffer = GetContext()->CreateCommandBuffer();
507  auto blit_pass = command_buffer->CreateBlitPass();
508 
509  blit_pass->AddCopy(DeviceBuffer::AsBufferView(std::move(device_buffer)),
510  texture);
511  blit_pass->GenerateMipmap(texture);
512  EXPECT_TRUE(blit_pass->EncodeCommands(GetContext()->GetResourceAllocator()));
513  EXPECT_TRUE(GetContext()->GetCommandQueue()->Submit({command_buffer}).ok());
514 
515  auto image = DlImageImpeller::Make(texture);
516 
517  DisplayListBuilder builder;
518  builder.DrawImageRect(
519  image,
520  SkRect::MakeSize(
521  SkSize::Make(texture->GetSize().width, texture->GetSize().height)),
522  SkRect::MakeLTRB(0, 0, 100, 100), DlImageSampling::kMipmapLinear);
523 
524  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
525 }

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() [218/454]

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({150, 200}, 100, paint);
180 
181  paint.setColor(DlColor::RGBA(0, 1, 0, 0.5));
182  builder.DrawCircle({250, 200}, 100, paint);
183 
184  paint.setBlendMode(DlBlendMode::kPlus);
185 
186  paint.setColor(DlColor::kRed());
187  builder.DrawCircle({450, 250}, 100, paint);
188 
189  paint.setColor(DlColor::kGreen());
190  builder.DrawCircle({550, 250}, 100, paint);
191 
192  paint.setColor(DlColor::kBlue());
193  builder.DrawCircle({500, 150}, 100, paint);
194 
195  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
196 }

◆ TEST_P() [219/454]

impeller::testing::TEST_P ( AiksTest  ,
PipelineBlendSingleParameter   
)

Definition at line 1489 of file aiks_dl_basic_unittests.cc.

1489  {
1490  DisplayListBuilder builder;
1491 
1492  // Should render a green square in the middle of a blue circle.
1493  DlPaint paint;
1494  builder.SaveLayer(nullptr, &paint);
1495  {
1496  builder.Translate(100, 100);
1497  paint.setColor(DlColor::kBlue());
1498  builder.DrawCircle(SkPoint::Make(200, 200), 200, paint);
1499  builder.ClipRect(SkRect::MakeXYWH(100, 100, 200, 200));
1500 
1501  paint.setColor(DlColor::kGreen());
1502  paint.setBlendMode(DlBlendMode::kSrcOver);
1503  paint.setImageFilter(DlColorFilterImageFilter::Make(
1504  DlBlendColorFilter::Make(DlColor::kWhite(), DlBlendMode::kDst)));
1505  builder.DrawCircle(SkPoint::Make(200, 200), 200, paint);
1506  builder.Restore();
1507  }
1508 
1509  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1510 }

◆ TEST_P() [220/454]

impeller::testing::TEST_P ( AiksTest  ,
ReleasesTextureOnTeardown   
)

Definition at line 585 of file aiks_dl_unittests.cc.

585  {
586  auto context = MakeContext();
587  std::weak_ptr<Texture> weak_texture;
588 
589  {
590  auto texture = CreateTextureForFixture("table_mountain_nx.png");
591  weak_texture = texture;
592 
593  DisplayListBuilder builder;
594  builder.Scale(GetContentScale().x, GetContentScale().y);
595  builder.Translate(100.0f, 100.0f);
596 
597  DlPaint paint;
598  paint.setColorSource(std::make_shared<DlImageColorSource>(
599  DlImageImpeller::Make(texture), DlTileMode::kClamp, DlTileMode::kClamp,
600  DlImageSampling::kLinear, nullptr));
601 
602  builder.DrawRect(SkRect::MakeXYWH(0, 0, 600, 600), paint);
603 
604  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
605  }
606 
607  // See https://github.com/flutter/flutter/issues/134751.
608  //
609  // If the fence waiter was working this may not be released by the end of the
610  // scope above. Adding a manual shutdown so that future changes to the fence
611  // waiter will not flake this test.
612  context->Shutdown();
613 
614  // The texture should be released by now.
615  ASSERT_TRUE(weak_texture.expired()) << "When the texture is no longer in use "
616  "by the backend, it should be "
617  "released.";
618 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [221/454]

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  DlBlendColorFilter::Make(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() [222/454]

impeller::testing::TEST_P ( AiksTest  ,
SaveLayerDrawsBehindSubsequentEntities   
)

Definition at line 1345 of file aiks_dl_basic_unittests.cc.

1345  {
1346  // Compare with https://fiddle.skia.org/c/9e03de8567ffb49e7e83f53b64bcf636
1347  DisplayListBuilder builder;
1348  DlPaint paint;
1349 
1350  paint.setColor(DlColor::kBlack());
1351  SkRect rect = SkRect::MakeXYWH(25, 25, 25, 25);
1352  builder.DrawRect(rect, paint);
1353 
1354  builder.Translate(10, 10);
1355 
1356  DlPaint save_paint;
1357  builder.SaveLayer(nullptr, &save_paint);
1358 
1359  paint.setColor(DlColor::kGreen());
1360  builder.DrawRect(rect, paint);
1361 
1362  builder.Restore();
1363 
1364  builder.Translate(10, 10);
1365  paint.setColor(DlColor::kRed());
1366  builder.DrawRect(rect, paint);
1367 
1368  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1369 }

◆ TEST_P() [223/454]

impeller::testing::TEST_P ( AiksTest  ,
SaveLayerFiltersScaleWithTransform   
)

Definition at line 1437 of file aiks_dl_basic_unittests.cc.

1437  {
1438  DisplayListBuilder builder;
1439 
1440  builder.Scale(GetContentScale().x, GetContentScale().y);
1441  builder.Translate(100, 100);
1442 
1443  auto texture = DlImageImpeller::Make(CreateTextureForFixture("boston.jpg"));
1444  auto draw_image_layer = [&builder, &texture](const DlPaint& paint) {
1445  builder.SaveLayer(nullptr, &paint);
1446  builder.DrawImage(texture, {}, DlImageSampling::kLinear);
1447  builder.Restore();
1448  };
1449 
1450  DlPaint effect_paint;
1451  effect_paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kNormal, 6));
1452  draw_image_layer(effect_paint);
1453 
1454  builder.Translate(300, 300);
1455  builder.Scale(3, 3);
1456  draw_image_layer(effect_paint);
1457 
1458  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1459 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [224/454]

impeller::testing::TEST_P ( AiksTest  ,
SetContentsWithRegion   
)

Definition at line 551 of file aiks_dl_unittests.cc.

551  {
552  auto bridge = CreateTextureForFixture("bay_bridge.jpg");
553 
554  // Replace part of the texture with a red rectangle.
555  std::vector<uint8_t> bytes(100 * 100 * 4);
556  for (auto i = 0u; i < bytes.size(); i += 4) {
557  bytes[i] = 255;
558  bytes[i + 1] = 0;
559  bytes[i + 2] = 0;
560  bytes[i + 3] = 255;
561  }
562  auto mapping =
563  std::make_shared<fml::NonOwnedMapping>(bytes.data(), bytes.size());
564  auto device_buffer =
565  GetContext()->GetResourceAllocator()->CreateBufferWithCopy(*mapping);
566  auto cmd_buffer = GetContext()->CreateCommandBuffer();
567  auto blit_pass = cmd_buffer->CreateBlitPass();
568  blit_pass->AddCopy(DeviceBuffer::AsBufferView(device_buffer), bridge,
569  IRect::MakeLTRB(50, 50, 150, 150));
570 
571  auto did_submit =
572  blit_pass->EncodeCommands(GetContext()->GetResourceAllocator()) &&
573  GetContext()->GetCommandQueue()->Submit({std::move(cmd_buffer)}).ok();
574  ASSERT_TRUE(did_submit);
575 
576  auto image = DlImageImpeller::Make(bridge);
577 
578  DisplayListBuilder builder;
579  builder.DrawImage(image, {0, 0}, {});
580 
581  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
582 }

References impeller::DeviceBuffer::AsBufferView(), impeller::DlImageImpeller::Make(), and impeller::TRect< T >::MakeLTRB().

◆ TEST_P() [225/454]

impeller::testing::TEST_P ( AiksTest  ,
SiblingSaveLayerBoundsAreRespected   
)

Definition at line 1371 of file aiks_dl_basic_unittests.cc.

1371  {
1372  DisplayListBuilder builder;
1373  DlPaint paint;
1374  SkRect rect = SkRect::MakeXYWH(0, 0, 1000, 1000);
1375 
1376  // Black, green, and red squares offset by [10, 10].
1377  {
1378  DlPaint save_paint;
1379  SkRect bounds = SkRect::MakeXYWH(25, 25, 25, 25);
1380  builder.SaveLayer(&bounds, &save_paint);
1381  paint.setColor(DlColor::kBlack());
1382  builder.DrawRect(rect, paint);
1383  builder.Restore();
1384  }
1385 
1386  {
1387  DlPaint save_paint;
1388  SkRect bounds = SkRect::MakeXYWH(35, 35, 25, 25);
1389  builder.SaveLayer(&bounds, &save_paint);
1390  paint.setColor(DlColor::kGreen());
1391  builder.DrawRect(rect, paint);
1392  builder.Restore();
1393  }
1394 
1395  {
1396  DlPaint save_paint;
1397  SkRect bounds = SkRect::MakeXYWH(45, 45, 25, 25);
1398  builder.SaveLayer(&bounds, &save_paint);
1399  paint.setColor(DlColor::kRed());
1400  builder.DrawRect(rect, paint);
1401  builder.Restore();
1402  }
1403 
1404  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1405 }

◆ TEST_P() [226/454]

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 }

◆ TEST_P() [227/454]

impeller::testing::TEST_P ( AiksTest  ,
SolidColorCirclesOvalsRRectsMaskBlurCorrectly   
)

Definition at line 723 of file aiks_dl_basic_unittests.cc.

723  {
724  DisplayListBuilder builder;
725  builder.Scale(GetContentScale().x, GetContentScale().y);
726  DlPaint paint;
727  paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kNormal, 1.0f));
728 
729  builder.DrawPaint(DlPaint().setColor(DlColor::kWhite()));
730 
731  paint.setColor(
732  DlColor::RGBA(220.0f / 255.0f, 20.0f / 255.0f, 60.0f / 255.0f, 1.0f));
733  Scalar y = 100.0f;
734  for (int i = 0; i < 5; i++) {
735  Scalar x = (i + 1) * 100;
736  Scalar radius = x / 10.0f;
737  builder.DrawRect(SkRect::MakeXYWH(x + 25 - radius / 2, y + radius / 2, //
738  radius, 60.0f - radius),
739  paint);
740  }
741 
742  paint.setColor(DlColor::kBlue());
743  y += 100.0f;
744  for (int i = 0; i < 5; i++) {
745  Scalar x = (i + 1) * 100;
746  Scalar radius = x / 10.0f;
747  builder.DrawCircle({x + 25, y + 25}, radius, paint);
748  }
749 
750  paint.setColor(DlColor::kGreen());
751  y += 100.0f;
752  for (int i = 0; i < 5; i++) {
753  Scalar x = (i + 1) * 100;
754  Scalar radius = x / 10.0f;
755  builder.DrawOval(SkRect::MakeXYWH(x + 25 - radius / 2, y + radius / 2, //
756  radius, 60.0f - radius),
757  paint);
758  }
759 
760  paint.setColor(
761  DlColor::RGBA(128.0f / 255.0f, 0.0f / 255.0f, 128.0f / 255.0f, 1.0f));
762  y += 100.0f;
763  for (int i = 0; i < 5; i++) {
764  Scalar x = (i + 1) * 100;
765  Scalar radius = x / 20.0f;
766  builder.DrawRRect(SkRRect::MakeRectXY(SkRect::MakeXYWH(x, y, 60.0f, 60.0f),
767  radius, radius),
768  paint);
769  }
770 
771  paint.setColor(
772  DlColor::RGBA(255.0f / 255.0f, 165.0f / 255.0f, 0.0f / 255.0f, 1.0f));
773  y += 100.0f;
774  for (int i = 0; i < 5; i++) {
775  Scalar x = (i + 1) * 100;
776  Scalar radius = x / 20.0f;
777  builder.DrawRRect(
778  SkRRect::MakeRectXY(SkRect::MakeXYWH(x, y, 60.0f, 60.0f), radius, 5.0f),
779  paint);
780  }
781 
782  auto dl = builder.Build();
783  ASSERT_TRUE(OpenPlaygroundHere(dl));
784 }

◆ TEST_P() [228/454]

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 }

◆ TEST_P() [229/454]

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::Black(), color, impeller::DrawPlaygroundLine(), impeller::AiksPlayground::ImGuiBegin(), impeller::Color::Red(), scale, and impeller::Color::WithAlpha().

◆ TEST_P() [230/454]

impeller::testing::TEST_P ( AiksTest  ,
SrgbToLinearFilterSubpassCollapseOptimization   
)

Definition at line 119 of file aiks_dl_unittests.cc.

119  {
120  DisplayListBuilder builder(GetCullRect(GetWindowSize()));
121 
122  DlPaint paint;
123  paint.setColorFilter(DlLinearToSrgbGammaColorFilter::kInstance);
124  builder.SaveLayer(nullptr, &paint);
125 
126  builder.Translate(500, 300);
127  builder.Rotate(120); // 120 deg
128 
129  DlPaint draw_paint;
130  draw_paint.setColor(DlColor::kBlue());
131  builder.DrawRect(SkRect::MakeXYWH(100, 100, 200, 200), draw_paint);
132 
133  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
134 }

◆ TEST_P() [231/454]

impeller::testing::TEST_P ( AiksTest  ,
StrokedCirclesRenderCorrectly   
)

Definition at line 477 of file aiks_dl_basic_unittests.cc.

477  {
478  DisplayListBuilder builder;
479  builder.Scale(GetContentScale().x, GetContentScale().y);
480  DlPaint paint;
481  const int color_count = 3;
482  DlColor colors[color_count] = {
483  DlColor::kBlue(),
484  DlColor::kGreen(),
485  DlColor::RGBA(220.0f / 255.0f, 20.0f / 255.0f, 60.0f / 255.0f, 1.0f),
486  };
487 
488  paint.setColor(DlColor::kWhite());
489  builder.DrawPaint(paint);
490 
491  int c_index = 0;
492 
493  auto draw = [&paint, &colors, &c_index](DlCanvas& canvas, SkPoint center,
494  Scalar r, Scalar dr, int n) {
495  for (int i = 0; i < n; i++) {
496  paint.setColor(colors[(c_index++) % color_count]);
497  canvas.DrawCircle(center, r, paint);
498  r += dr;
499  }
500  };
501 
502  paint.setDrawStyle(DlDrawStyle::kStroke);
503  paint.setStrokeWidth(1);
504  draw(builder, {10, 10}, 2, 2, 14); // r = [2, 28], covers [1,29]
505  paint.setStrokeWidth(5);
506  draw(builder, {10, 10}, 35, 10, 56); // r = [35, 585], covers [30,590]
507 
508  DlColor gradient_colors[7] = {
509  DlColor::RGBA(0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0),
510  DlColor::RGBA(0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0),
511  DlColor::RGBA(0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0),
512  DlColor::RGBA(0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0),
513  DlColor::RGBA(0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0),
514  DlColor::RGBA(0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0),
515  DlColor::RGBA(0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0),
516  };
517  DlScalar stops[7] = {
518  0.0,
519  (1.0 / 6.0) * 1,
520  (1.0 / 6.0) * 2,
521  (1.0 / 6.0) * 3,
522  (1.0 / 6.0) * 4,
523  (1.0 / 6.0) * 5,
524  1.0,
525  };
526  auto texture = CreateTextureForFixture("airplane.jpg",
527  /*enable_mipmapping=*/true);
528  auto image = DlImageImpeller::Make(texture);
529 
530  paint.setColorSource(DlColorSource::MakeRadial(
531  {500, 600}, 75, 7, gradient_colors, stops, DlTileMode::kMirror));
532  draw(builder, {500, 600}, 5, 10, 10);
533 
534  SkMatrix local_matrix = SkMatrix::Translate(700, 200);
535  DlImageColorSource image_source(
536  image, DlTileMode::kRepeat, DlTileMode::kRepeat,
537  DlImageSampling::kNearestNeighbor, &local_matrix);
538  paint.setColorSource(&image_source);
539  draw(builder, {800, 300}, 5, 10, 10);
540 
541  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
542 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [232/454]

impeller::testing::TEST_P ( AiksTest  ,
StrokedPathWithMoveToThenCloseDrawnCorrectly   
)

Definition at line 528 of file aiks_dl_unittests.cc.

528  {
529  SkPath path;
530  path.moveTo(0, 400)
531  .lineTo(0, 0)
532  .lineTo(400, 0)
533  // MoveTo implicitly adds a contour, ensure that close doesn't
534  // add another nearly-empty contour.
535  .moveTo(0, 400)
536  .close();
537 
538  DisplayListBuilder builder;
539  builder.Translate(50, 50);
540 
541  DlPaint paint;
542  paint.setColor(DlColor::kBlue());
543  paint.setStrokeCap(DlStrokeCap::kRound);
544  paint.setStrokeWidth(10);
545  paint.setDrawStyle(DlDrawStyle::kStroke);
546  builder.DrawPath(path, paint);
547 
548  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
549 }

◆ TEST_P() [233/454]

impeller::testing::TEST_P ( AiksTest  ,
SubpassWithClearColorOptimization   
)

Definition at line 943 of file aiks_dl_basic_unittests.cc.

943  {
944  DisplayListBuilder builder;
945 
946  // Use a non-srcOver blend mode to ensure that we don't detect this as an
947  // opacity peephole optimization.
948  DlPaint paint;
949  paint.setColor(DlColor::kBlue().modulateOpacity(0.5));
950  paint.setBlendMode(DlBlendMode::kSrc);
951 
952  SkRect bounds = SkRect::MakeLTRB(0, 0, 200, 200);
953  builder.SaveLayer(&bounds, &paint);
954 
955  paint.setColor(DlColor::kTransparent());
956  paint.setBlendMode(DlBlendMode::kSrc);
957  builder.DrawPaint(paint);
958  builder.Restore();
959 
960  paint.setColor(DlColor::kBlue());
961  paint.setBlendMode(DlBlendMode::kDstOver);
962  builder.SaveLayer(nullptr, &paint);
963  builder.Restore();
964 
965  // This playground should appear blank on CI since we are only drawing
966  // transparent black. If the clear color optimization is broken, the texture
967  // will be filled with NaNs and may produce a magenta texture on macOS or iOS.
968  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
969 }

◆ TEST_P() [234/454]

impeller::testing::TEST_P ( AiksTest  ,
TextForegroundShaderWithTransform   
)

Definition at line 500 of file aiks_dl_text_unittests.cc.

500  {
501  auto mapping = flutter::testing::OpenFixtureAsSkData("Roboto-Regular.ttf");
502  ASSERT_NE(mapping, nullptr);
503 
504  Scalar font_size = 100;
505  sk_sp<SkFontMgr> font_mgr = txt::GetDefaultFontManager();
506  SkFont sk_font(font_mgr->makeFromData(mapping), font_size);
507 
508  DlPaint text_paint;
509  text_paint.setColor(DlColor::kBlue());
510 
511  std::vector<DlColor> colors = {DlColor::RGBA(0.9568, 0.2627, 0.2118, 1.0),
512  DlColor::RGBA(0.1294, 0.5882, 0.9529, 1.0)};
513  std::vector<Scalar> stops = {
514  0.0,
515  1.0,
516  };
517  text_paint.setColorSource(DlColorSource::MakeLinear(
518  /*start_point=*/{0, 0}, //
519  /*end_point=*/{100, 100}, //
520  /*stop_count=*/2, //
521  /*colors=*/colors.data(), //
522  /*stops=*/stops.data(), //
523  /*tile_mode=*/DlTileMode::kRepeat //
524  ));
525 
526  DisplayListBuilder builder;
527  builder.Translate(100, 100);
528  builder.Rotate(45);
529 
530  auto blob = SkTextBlob::MakeFromString("Hello", sk_font);
531  ASSERT_NE(blob, nullptr);
532  auto frame = MakeTextFrameFromTextBlobSkia(blob);
533  builder.DrawTextFrame(frame, 0, 0, text_paint);
534 
535  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
536 }

References font_size, and impeller::MakeTextFrameFromTextBlobSkia().

◆ TEST_P() [235/454]

impeller::testing::TEST_P ( AiksTest  ,
TextFrameSubpixelAlignment   
)

Definition at line 222 of file aiks_dl_text_unittests.cc.

222  {
223  // "Random" numbers between 0 and 1. Hardcoded to avoid flakiness in goldens.
224  std::array<Scalar, 20> phase_offsets = {
225  7.82637e-06, 0.131538, 0.755605, 0.45865, 0.532767,
226  0.218959, 0.0470446, 0.678865, 0.679296, 0.934693,
227  0.383502, 0.519416, 0.830965, 0.0345721, 0.0534616,
228  0.5297, 0.671149, 0.00769819, 0.383416, 0.0668422};
229  auto callback = [&]() -> sk_sp<DisplayList> {
230  static float font_size = 20;
231  static float phase_variation = 0.2;
232  static float speed = 0.5;
233  static float magnitude = 100;
234  if (AiksTest::ImGuiBegin("Controls", nullptr,
235  ImGuiWindowFlags_AlwaysAutoResize)) {
236  ImGui::SliderFloat("Font size", &font_size, 5, 50);
237  ImGui::SliderFloat("Phase variation", &phase_variation, 0, 1);
238  ImGui::SliderFloat("Oscillation speed", &speed, 0, 2);
239  ImGui::SliderFloat("Oscillation magnitude", &magnitude, 0, 300);
240  ImGui::End();
241  }
242 
243  DisplayListBuilder builder;
244  builder.Scale(GetContentScale().x, GetContentScale().y);
245 
246  for (size_t i = 0; i < phase_offsets.size(); i++) {
247  SkPoint position = SkPoint::Make(
248  200 +
249  magnitude * std::sin((-phase_offsets[i] * k2Pi * phase_variation +
250  GetSecondsElapsed() * speed)), //
251  200 + i * font_size * 1.1 //
252  );
254  GetContext(), builder,
255  "the quick brown fox jumped over "
256  "the lazy dog!.?",
257  "Roboto-Regular.ttf",
258  {.font_size = font_size, .position = position})) {
259  return nullptr;
260  }
261  }
262  return builder.Build();
263  };
264 
265  ASSERT_TRUE(OpenPlaygroundHere(callback));
266 }

References font_size, impeller::k2Pi, and RenderTextInCanvasSkia().

◆ TEST_P() [236/454]

impeller::testing::TEST_P ( AiksTest  ,
TextRotated   
)

Definition at line 394 of file aiks_dl_text_unittests.cc.

394  {
395  DisplayListBuilder builder;
396 
397  builder.Scale(GetContentScale().x, GetContentScale().y);
398  DlPaint paint;
399  paint.setColor(DlColor::ARGB(0.1, 0.1, 0.1, 1.0));
400  builder.DrawPaint(paint);
401 
402  builder.Transform(SkM44::ColMajor(Matrix(0.25, -0.3, 0, -0.002, //
403  0, 0.5, 0, 0, //
404  0, 0, 0.3, 0, //
405  100, 100, 0, 1.3)
406  .m));
407  ASSERT_TRUE(RenderTextInCanvasSkia(
408  GetContext(), builder, "the quick brown fox jumped over the lazy dog!.?",
409  "Roboto-Regular.ttf"));
410 
411  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
412 }

References RenderTextInCanvasSkia().

◆ TEST_P() [237/454]

impeller::testing::TEST_P ( AiksTest  ,
TransformMultipliesCorrectly   
)

Definition at line 26 of file canvas_unittests.cc.

26  {
27  ContentContext context(GetContext(), nullptr);
28  auto canvas = CreateTestCanvas(context);
29 
30  ASSERT_MATRIX_NEAR(canvas->GetCurrentTransform(), Matrix());
31 
32  // clang-format off
33  canvas->Translate(Vector3(100, 200));
35  canvas->GetCurrentTransform(),
36  Matrix( 1, 0, 0, 0,
37  0, 1, 0, 0,
38  0, 0, 1, 0,
39  100, 200, 0, 1));
40 
41  canvas->Rotate(Radians(kPiOver2));
43  canvas->GetCurrentTransform(),
44  Matrix( 0, 1, 0, 0,
45  -1, 0, 0, 0,
46  0, 0, 1, 0,
47  100, 200, 0, 1));
48 
49  canvas->Scale(Vector3(2, 3));
51  canvas->GetCurrentTransform(),
52  Matrix( 0, 2, 0, 0,
53  -3, 0, 0, 0,
54  0, 0, 0, 0,
55  100, 200, 0, 1));
56 
57  canvas->Translate(Vector3(100, 200));
59  canvas->GetCurrentTransform(),
60  Matrix( 0, 2, 0, 0,
61  -3, 0, 0, 0,
62  0, 0, 0, 0,
63  -500, 400, 0, 1));
64  // clang-format on
65 }

References ASSERT_MATRIX_NEAR, CreateTestCanvas(), and impeller::kPiOver2.

◆ TEST_P() [238/454]

impeller::testing::TEST_P ( AiksTest  ,
TranslucentSaveLayerDrawsCorrectly   
)

Definition at line 136 of file aiks_dl_unittests.cc.

136  {
137  DisplayListBuilder builder(GetCullRect(GetWindowSize()));
138 
139  DlPaint paint;
140  paint.setColor(DlColor::kBlue());
141  builder.DrawRect(SkRect::MakeXYWH(100, 100, 300, 300), paint);
142 
143  DlPaint save_paint;
144  save_paint.setColor(DlColor::kBlack().withAlpha(128));
145  builder.SaveLayer(nullptr, &save_paint);
146  builder.DrawRect(SkRect::MakeXYWH(100, 500, 300, 300), paint);
147  builder.Restore();
148 
149  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
150 }

◆ TEST_P() [239/454]

impeller::testing::TEST_P ( AiksTest  ,
TranslucentSaveLayerImageDrawsCorrectly   
)

Definition at line 241 of file aiks_dl_unittests.cc.

241  {
242  DisplayListBuilder builder(GetCullRect(GetWindowSize()));
243 
244  auto image = DlImageImpeller::Make(CreateTextureForFixture("airplane.jpg"));
245  builder.DrawImage(image, {100, 100}, DlImageSampling::kMipmapLinear);
246 
247  DlPaint paint;
248  paint.setColor(DlColor::kBlack().withAlpha(128));
249  builder.SaveLayer(nullptr, &paint);
250  builder.DrawImage(image, {100, 500}, DlImageSampling::kMipmapLinear);
251  builder.Restore();
252 
253  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
254 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [240/454]

impeller::testing::TEST_P ( AiksTest  ,
TranslucentSaveLayerWithAdvancedBlendModeDrawsCorrectly   
)

Definition at line 326 of file aiks_dl_unittests.cc.

326  {
327  DisplayListBuilder builder(GetCullRect(GetWindowSize()));
328 
329  DlPaint paint;
330  paint.setColor(DlColor::kRed());
331  builder.DrawRect(SkRect::MakeXYWH(0, 0, 400, 400), paint);
332 
333  DlPaint save_paint;
334  save_paint.setAlpha(128);
335  save_paint.setBlendMode(DlBlendMode::kLighten);
336  builder.SaveLayer(nullptr, &save_paint);
337 
338  DlPaint draw_paint;
339  draw_paint.setColor(DlColor::kGreen());
340  builder.DrawCircle({200, 200}, 100, draw_paint);
341  builder.Restore();
342 
343  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
344 }

◆ TEST_P() [241/454]

impeller::testing::TEST_P ( AiksTest  ,
TranslucentSaveLayerWithBlendColorFilterDrawsCorrectly   
)

Definition at line 152 of file aiks_dl_unittests.cc.

152  {
153  DisplayListBuilder builder(GetCullRect(GetWindowSize()));
154 
155  DlPaint paint;
156  paint.setColor(DlColor::kBlue());
157  builder.DrawRect(SkRect::MakeXYWH(100, 100, 300, 300), paint);
158 
159  DlPaint save_paint;
160  paint.setColor(DlColor::kBlack().withAlpha(128));
161  paint.setColorFilter(
162  DlBlendColorFilter::Make(DlColor::kRed(), DlBlendMode::kDstOver));
163  builder.SaveLayer(nullptr, &paint);
164 
165  DlPaint draw_paint;
166  draw_paint.setColor(DlColor::kBlue());
167  builder.DrawRect(SkRect::MakeXYWH(100, 500, 300, 300), draw_paint);
168  builder.Restore();
169 
170  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
171 }

◆ TEST_P() [242/454]

impeller::testing::TEST_P ( AiksTest  ,
TranslucentSaveLayerWithBlendImageFilterDrawsCorrectly   
)

Definition at line 173 of file aiks_dl_unittests.cc.

173  {
174  DisplayListBuilder builder(GetCullRect(GetWindowSize()));
175 
176  DlPaint paint;
177  paint.setColor(DlColor::kBlue());
178  builder.DrawRect(SkRect::MakeXYWH(100, 100, 300, 300), paint);
179 
180  DlPaint save_paint;
181  save_paint.setColor(DlColor::kBlack().withAlpha(128));
182  save_paint.setImageFilter(DlColorFilterImageFilter::Make(
183  DlBlendColorFilter::Make(DlColor::kRed(), DlBlendMode::kDstOver)));
184 
185  builder.SaveLayer(nullptr, &save_paint);
186 
187  DlPaint draw_paint;
188  draw_paint.setColor(DlColor::kBlue());
189  builder.DrawRect(SkRect::MakeXYWH(100, 500, 300, 300), draw_paint);
190  builder.Restore();
191 
192  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
193 }

◆ TEST_P() [243/454]

impeller::testing::TEST_P ( AiksTest  ,
TranslucentSaveLayerWithColorAndImageFilterDrawsCorrectly   
)

Definition at line 195 of file aiks_dl_unittests.cc.

195  {
196  DisplayListBuilder builder(GetCullRect(GetWindowSize()));
197 
198  DlPaint paint;
199  paint.setColor(DlColor::kBlue());
200  builder.DrawRect(SkRect::MakeXYWH(100, 100, 300, 300), paint);
201 
202  DlPaint save_paint;
203  save_paint.setColor(DlColor::kBlack().withAlpha(128));
204  save_paint.setColorFilter(
205  DlBlendColorFilter::Make(DlColor::kRed(), DlBlendMode::kDstOver));
206  builder.SaveLayer(nullptr, &save_paint);
207 
208  DlPaint draw_paint;
209  draw_paint.setColor(DlColor::kBlue());
210  builder.DrawRect(SkRect::MakeXYWH(100, 500, 300, 300), draw_paint);
211  builder.Restore();
212 
213  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
214 }

◆ TEST_P() [244/454]

impeller::testing::TEST_P ( AiksTest  ,
TranslucentSaveLayerWithColorFilterAndImageFilterDrawsCorrectly   
)

Definition at line 300 of file aiks_dl_unittests.cc.

301  {
302  DisplayListBuilder builder(GetCullRect(GetWindowSize()));
303 
304  auto image = DlImageImpeller::Make(CreateTextureForFixture("airplane.jpg"));
305  builder.DrawImage(image, {100, 100}, {});
306 
307  const float matrix[20] = {
308  1, 0, 0, 0, 0, //
309  0, 1, 0, 0, 0, //
310  0, 0.2, 1, 0, 0, //
311  0, 0, 0, 0.5, 0 //
312  };
313  DlPaint paint;
314  paint.setColor(DlColor::kBlack().withAlpha(128));
315  paint.setImageFilter(
316  DlColorFilterImageFilter::Make(DlMatrixColorFilter::Make(matrix)));
317  paint.setColorFilter(
318  DlBlendColorFilter::Make(DlColor::kGreen(), DlBlendMode::kModulate));
319  builder.SaveLayer(nullptr, &paint);
320  builder.DrawImage(image, {100, 500}, {});
321  builder.Restore();
322 
323  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
324 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [245/454]

impeller::testing::TEST_P ( AiksTest  ,
TranslucentSaveLayerWithColorMatrixColorFilterDrawsCorrectly   
)

Definition at line 256 of file aiks_dl_unittests.cc.

256  {
257  DisplayListBuilder builder(GetCullRect(GetWindowSize()));
258 
259  auto image = DlImageImpeller::Make(CreateTextureForFixture("airplane.jpg"));
260  builder.DrawImage(image, {100, 100}, {});
261 
262  const float matrix[20] = {
263  1, 0, 0, 0, 0, //
264  0, 1, 0, 0, 0, //
265  0, 0, 1, 0, 0, //
266  0, 0, 0, 2, 0 //
267  };
268  DlPaint paint;
269  paint.setColor(DlColor::kBlack().withAlpha(128));
270  paint.setColorFilter(DlMatrixColorFilter::Make(matrix));
271  builder.SaveLayer(nullptr, &paint);
272  builder.DrawImage(image, {100, 500}, {});
273  builder.Restore();
274 
275  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
276 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [246/454]

impeller::testing::TEST_P ( AiksTest  ,
TranslucentSaveLayerWithColorMatrixImageFilterDrawsCorrectly   
)

Definition at line 278 of file aiks_dl_unittests.cc.

278  {
279  DisplayListBuilder builder(GetCullRect(GetWindowSize()));
280 
281  auto image = DlImageImpeller::Make(CreateTextureForFixture("airplane.jpg"));
282  builder.DrawImage(image, {100, 100}, {});
283 
284  const float matrix[20] = {
285  1, 0, 0, 0, 0, //
286  0, 1, 0, 0, 0, //
287  0, 0, 1, 0, 0, //
288  0, 0, 0, 2, 0 //
289  };
290  DlPaint paint;
291  paint.setColor(DlColor::kBlack().withAlpha(128));
292  paint.setColorFilter(DlMatrixColorFilter::Make(matrix));
293  builder.SaveLayer(nullptr, &paint);
294  builder.DrawImage(image, {100, 500}, {});
295  builder.Restore();
296 
297  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
298 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [247/454]

impeller::testing::TEST_P ( AiksTest  ,
TransparentShadowProducesCorrectColor   
)

Definition at line 851 of file aiks_dl_unittests.cc.

851  {
852  DisplayListBuilder builder;
853  builder.Save();
854  builder.Scale(1.618, 1.618);
855  SkPath path = SkPath{}.addRect(SkRect::MakeXYWH(0, 0, 200, 100));
856 
857  builder.DrawShadow(path, flutter::DlColor::kTransparent(), 15, false, 1);
858  builder.Restore();
859 
860  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
861 }

◆ TEST_P() [248/454]

impeller::testing::TEST_P ( AiksTest  ,
VerifyNonOptimizedGradient   
)

Definition at line 807 of file aiks_dl_gradient_unittests.cc.

807  {
808  DisplayListBuilder builder;
809  DlPaint paint;
810  builder.Translate(100.0f, 0);
811 
812  std::vector<DlColor> colors = {DlColor::kRed(), DlColor::kBlue(),
813  DlColor::kGreen()};
814  std::vector<Scalar> stops = {0.0, 0.1, 1.0};
815 
816  // Inset the start and end point to verify that we do not apply
817  // the fast gradient condition.
818  paint.setColorSource(
819  DlColorSource::MakeLinear({0, 150}, {0, 100}, stops.size(), colors.data(),
820  stops.data(), DlTileMode::kRepeat));
821 
822  paint.setColor(DlColor::kWhite());
823  builder.DrawRect(SkRect::MakeXYWH(0, 0, 300, 300), paint);
824  builder.Translate(400, 0);
825  builder.DrawRRect(SkRRect::MakeRectXY(SkRect::MakeXYWH(0, 0, 300, 300), 4, 4),
826  paint);
827 
828  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
829 }

◆ TEST_P() [249/454]

impeller::testing::TEST_P ( AiksTest  ,
VerticesGeometryColorUVPositionData   
)

Definition at line 94 of file aiks_dl_vertices_unittests.cc.

94  {
95  DisplayListBuilder builder;
96  DlPaint paint;
97  auto image =
98  DlImageImpeller::Make(CreateTextureForFixture("table_mountain_nx.png"));
99  auto size = image->impeller_texture()->GetSize();
100 
101  paint.setColorSource(std::make_shared<DlImageColorSource>(
102  image, DlTileMode::kClamp, DlTileMode::kClamp));
103 
104  std::vector<SkPoint> positions = {
105  SkPoint::Make(0, 0), SkPoint::Make(size.width, 0),
106  SkPoint::Make(0, size.height), SkPoint::Make(size.width, 0),
107  SkPoint::Make(0, 0), SkPoint::Make(size.width, size.height),
108  };
109  std::vector<DlColor> colors = {
110  DlColor::kRed().withAlpha(128), DlColor::kBlue().withAlpha(128),
111  DlColor::kGreen().withAlpha(128), DlColor::kRed().withAlpha(128),
112  DlColor::kBlue().withAlpha(128), DlColor::kGreen().withAlpha(128),
113  };
114 
115  auto vertices =
116  MakeVertices(DlVertexMode::kTriangles, positions, {}, {}, colors);
117 
118  builder.DrawVertices(vertices, DlBlendMode::kDstOver, paint);
119  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
120 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [250/454]

impeller::testing::TEST_P ( AiksTest  ,
VerticesGeometryColorUVPositionDataAdvancedBlend   
)

Definition at line 122 of file aiks_dl_vertices_unittests.cc.

122  {
123  DisplayListBuilder builder;
124  DlPaint paint;
125  auto image =
126  DlImageImpeller::Make(CreateTextureForFixture("table_mountain_nx.png"));
127  auto size = image->impeller_texture()->GetSize();
128 
129  paint.setColorSource(std::make_shared<DlImageColorSource>(
130  image, DlTileMode::kClamp, DlTileMode::kClamp));
131 
132  std::vector<SkPoint> positions = {
133  SkPoint::Make(0, 0), SkPoint::Make(size.width, 0),
134  SkPoint::Make(0, size.height), SkPoint::Make(size.width, 0),
135  SkPoint::Make(0, 0), SkPoint::Make(size.width, size.height),
136  };
137  std::vector<DlColor> colors = {
138  DlColor::kRed().modulateOpacity(0.5),
139  DlColor::kBlue().modulateOpacity(0.5),
140  DlColor::kGreen().modulateOpacity(0.5),
141  DlColor::kRed().modulateOpacity(0.5),
142  DlColor::kBlue().modulateOpacity(0.5),
143  DlColor::kGreen().modulateOpacity(0.5),
144  };
145 
146  auto vertices =
147  MakeVertices(DlVertexMode::kTriangles, positions, {}, {}, colors);
148 
149  builder.DrawVertices(vertices, DlBlendMode::kColorBurn, paint);
150  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
151 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [251/454]

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(std::make_shared<DlImageColorSource>(
56  image, DlTileMode::kClamp, DlTileMode::kClamp));
57 
58  std::vector<SkPoint> vertex_coordinates = {SkPoint::Make(0, 0),
59  SkPoint::Make(size.width, 0),
60  SkPoint::Make(0, size.height)};
61  auto vertices = MakeVertices(DlVertexMode::kTriangleStrip, vertex_coordinates,
62  {0, 1, 2}, {}, {});
63 
64  builder.DrawVertices(vertices, DlBlendMode::kSrcOver, paint);
65  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
66 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [252/454]

impeller::testing::TEST_P ( AiksTest  ,
VerticesGeometryUVPositionDataWithTranslate   
)

Definition at line 69 of file aiks_dl_vertices_unittests.cc.

69  {
70  DisplayListBuilder builder;
71  DlPaint paint;
72  auto image =
73  DlImageImpeller::Make(CreateTextureForFixture("table_mountain_nx.png"));
74  auto size = image->impeller_texture()->GetSize();
75 
76  SkMatrix matrix;
77  matrix.setTranslateX(100);
78  matrix.setTranslateY(100);
79  paint.setColorSource(std::make_shared<DlImageColorSource>(
80  image, DlTileMode::kClamp, DlTileMode::kClamp, DlImageSampling::kLinear,
81  &matrix));
82 
83  std::vector<SkPoint> positions = {SkPoint::Make(0, 0),
84  SkPoint::Make(size.width, 0),
85  SkPoint::Make(0, size.height)};
86  auto vertices =
87  MakeVertices(DlVertexMode::kTriangleStrip, positions, {0, 1, 2}, {}, {});
88 
89  builder.DrawVertices(vertices, DlBlendMode::kSrcOver, paint);
90  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
91 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [253/454]

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() [254/454]

impeller::testing::TEST_P ( BlendFilterContentsTest  ,
AdvancedBlendColorAlignsColorTo4   
)

Definition at line 45 of file blend_filter_contents_unittests.cc.

45  {
46  std::shared_ptr<Texture> texture = MakeTexture(ISize(100, 100));
47  BlendFilterContents filter_contents;
48  filter_contents.SetInputs({FilterInput::Make(texture)});
49  filter_contents.SetForegroundColor(Color(1.0, 0.0, 0.0, 1.0));
50  filter_contents.SetBlendMode(BlendMode::kColorDodge);
51 
52  std::shared_ptr<ContentContext> renderer = GetContentContext();
53  // Add random byte to get the HostBuffer in a bad alignment.
54  uint8_t byte = 0xff;
55  BufferView buffer_view =
56  renderer->GetTransientsBuffer().Emplace(&byte, /*length=*/1, /*align=*/1);
57  EXPECT_EQ(buffer_view.range.offset, 4u);
58  EXPECT_EQ(buffer_view.range.length, 1u);
59  Entity entity;
60 
61  std::optional<Entity> result = filter_contents.GetEntity(
62  *renderer, entity, /*coverage_hint=*/std::nullopt);
63 
64  EXPECT_TRUE(result.has_value());
65 }

References buffer_view, impeller::FilterContents::GetEntity(), impeller::kColorDodge, impeller::FilterInput::Make(), impeller::BlendFilterContents::SetBlendMode(), impeller::BlendFilterContents::SetForegroundColor(), and impeller::FilterContents::SetInputs().

◆ TEST_P() [255/454]

impeller::testing::TEST_P ( BlitPassTest  ,
BlitAcrossDifferentPixelFormatsFails   
)

Definition at line 22 of file blit_pass_unittests.cc.

22  {
23  ScopedValidationDisable scope; // avoid noise in output.
24  auto context = GetContext();
25  auto cmd_buffer = context->CreateCommandBuffer();
26  auto blit_pass = cmd_buffer->CreateBlitPass();
27 
28  TextureDescriptor src_desc;
29  src_desc.format = PixelFormat::kA8UNormInt;
30  src_desc.size = {100, 100};
31  src_desc.storage_mode = StorageMode::kHostVisible;
32  auto src = context->GetResourceAllocator()->CreateTexture(src_desc);
33 
34  TextureDescriptor dst_format;
35  dst_format.format = PixelFormat::kR8G8B8A8UNormInt;
36  dst_format.size = {100, 100};
37  dst_format.storage_mode = StorageMode::kHostVisible;
38  auto dst = context->GetResourceAllocator()->CreateTexture(dst_format);
39 
40  EXPECT_FALSE(blit_pass->AddCopy(src, dst));
41 }

References impeller::TextureDescriptor::format, impeller::kA8UNormInt, impeller::kHostVisible, impeller::kR8G8B8A8UNormInt, impeller::TextureDescriptor::size, and impeller::TextureDescriptor::storage_mode.

◆ TEST_P() [256/454]

impeller::testing::TEST_P ( BlitPassTest  ,
BlitAcrossDifferentSampleCountsFails   
)

Definition at line 43 of file blit_pass_unittests.cc.

43  {
44  ScopedValidationDisable scope; // avoid noise in output.
45  auto context = GetContext();
46  auto cmd_buffer = context->CreateCommandBuffer();
47  auto blit_pass = cmd_buffer->CreateBlitPass();
48 
49  TextureDescriptor src_desc;
50  src_desc.format = PixelFormat::kR8G8B8A8UNormInt;
51  src_desc.sample_count = SampleCount::kCount4;
52  src_desc.size = {100, 100};
53  auto src = context->GetResourceAllocator()->CreateTexture(src_desc);
54 
55  TextureDescriptor dst_format;
56  dst_format.format = PixelFormat::kR8G8B8A8UNormInt;
57  dst_format.size = {100, 100};
58  auto dst = context->GetResourceAllocator()->CreateTexture(dst_format);
59 
60  EXPECT_FALSE(blit_pass->AddCopy(src, dst));
61 }

References impeller::TextureDescriptor::format, impeller::kCount4, impeller::kR8G8B8A8UNormInt, impeller::TextureDescriptor::sample_count, and impeller::TextureDescriptor::size.

◆ TEST_P() [257/454]

impeller::testing::TEST_P ( BlitPassTest  ,
BlitPassesForMatchingFormats   
)

Definition at line 63 of file blit_pass_unittests.cc.

63  {
64  ScopedValidationDisable scope; // avoid noise in output.
65  auto context = GetContext();
66  auto cmd_buffer = context->CreateCommandBuffer();
67  auto blit_pass = cmd_buffer->CreateBlitPass();
68 
69  TextureDescriptor src_desc;
70  src_desc.format = PixelFormat::kR8G8B8A8UNormInt;
71  src_desc.size = {100, 100};
72  src_desc.storage_mode = StorageMode::kHostVisible;
73  auto src = context->GetResourceAllocator()->CreateTexture(src_desc);
74 
75  TextureDescriptor dst_format;
76  dst_format.format = PixelFormat::kR8G8B8A8UNormInt;
77  dst_format.size = {100, 100};
78  dst_format.storage_mode = StorageMode::kHostVisible;
79  auto dst = context->GetResourceAllocator()->CreateTexture(dst_format);
80 
81  EXPECT_TRUE(blit_pass->AddCopy(src, dst));
82 }

References impeller::TextureDescriptor::format, impeller::kHostVisible, impeller::kR8G8B8A8UNormInt, impeller::TextureDescriptor::size, and impeller::TextureDescriptor::storage_mode.

◆ TEST_P() [258/454]

impeller::testing::TEST_P ( BlitPassTest  ,
CanBlitSmallRegionToUninitializedTexture   
)

Definition at line 112 of file blit_pass_unittests.cc.

112  {
113  auto context = GetContext();
114  auto cmd_buffer = context->CreateCommandBuffer();
115  auto blit_pass = cmd_buffer->CreateBlitPass();
116 
117  TextureDescriptor dst_format;
118  dst_format.storage_mode = StorageMode::kDevicePrivate;
119  dst_format.format = PixelFormat::kR8G8B8A8UNormInt;
120  dst_format.size = {1000, 1000};
121  auto dst = context->GetResourceAllocator()->CreateTexture(dst_format);
122 
123  DeviceBufferDescriptor src_format;
124  src_format.size = 4;
125  src_format.storage_mode = StorageMode::kHostVisible;
126  auto src = context->GetResourceAllocator()->CreateBuffer(src_format);
127 
128  ASSERT_TRUE(dst);
129 
130  EXPECT_TRUE(blit_pass->AddCopy(DeviceBuffer::AsBufferView(src), dst,
131  IRect::MakeLTRB(0, 0, 1, 1), "", /*slice=*/0));
132  EXPECT_TRUE(blit_pass->EncodeCommands(GetContext()->GetResourceAllocator()));
133  EXPECT_TRUE(context->GetCommandQueue()->Submit({std::move(cmd_buffer)}).ok());
134 }

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() [259/454]

impeller::testing::TEST_P ( BlitPassTest  ,
CanResizeTextures   
)

Definition at line 136 of file blit_pass_unittests.cc.

136  {
137  auto context = GetContext();
138  auto cmd_buffer = context->CreateCommandBuffer();
139  auto blit_pass = cmd_buffer->CreateBlitPass();
140 
141  TextureDescriptor dst_format;
142  dst_format.storage_mode = StorageMode::kDevicePrivate;
143  dst_format.format = PixelFormat::kR8G8B8A8UNormInt;
144  dst_format.size = {10, 10};
145  dst_format.usage = TextureUsage::kShaderRead | TextureUsage::kShaderWrite;
146  auto dst = context->GetResourceAllocator()->CreateTexture(dst_format);
147 
148  TextureDescriptor src_format;
149  src_format.storage_mode = StorageMode::kDevicePrivate;
150  src_format.format = PixelFormat::kR8G8B8A8UNormInt;
151  src_format.size = {100, 100};
152  auto src = context->GetResourceAllocator()->CreateTexture(src_format);
153 
154  std::vector<uint8_t> bytes(src_format.GetByteSizeOfBaseMipLevel());
155  for (auto i = 0u; i < src_format.GetByteSizeOfBaseMipLevel(); i += 4) {
156  // RGBA
157  bytes[i + 0] = 255;
158  bytes[i + 1] = 0;
159  bytes[i + 2] = 0;
160  bytes[i + 3] = 255;
161  }
162  auto mapping = fml::DataMapping(bytes);
163  auto staging = context->GetResourceAllocator()->CreateBufferWithCopy(mapping);
164 
165  ASSERT_TRUE(dst);
166  ASSERT_TRUE(src);
167  ASSERT_TRUE(staging);
168 
169  EXPECT_TRUE(blit_pass->AddCopy(DeviceBuffer::AsBufferView(staging), src));
170  EXPECT_TRUE(blit_pass->ResizeTexture(src, dst));
171  EXPECT_TRUE(blit_pass->EncodeCommands(GetContext()->GetResourceAllocator()));
172  EXPECT_TRUE(context->GetCommandQueue()->Submit({std::move(cmd_buffer)}).ok());
173 }

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() [260/454]

impeller::testing::TEST_P ( BlitPassTest  ,
ChecksInvalidSliceParameters   
)

Definition at line 84 of file blit_pass_unittests.cc.

84  {
85  ScopedValidationDisable scope; // avoid noise in output.
86  auto context = GetContext();
87  auto cmd_buffer = context->CreateCommandBuffer();
88  auto blit_pass = cmd_buffer->CreateBlitPass();
89 
90  TextureDescriptor dst_format;
91  dst_format.storage_mode = StorageMode::kDevicePrivate;
92  dst_format.format = PixelFormat::kR8G8B8A8UNormInt;
93  dst_format.size = {100, 100};
94  auto dst = context->GetResourceAllocator()->CreateTexture(dst_format);
95 
96  DeviceBufferDescriptor src_format;
97  src_format.size = 40000;
98  src_format.storage_mode = StorageMode::kHostVisible;
99  auto src = context->GetResourceAllocator()->CreateBuffer(src_format);
100 
101  ASSERT_TRUE(dst);
102  ASSERT_TRUE(src);
103 
104  EXPECT_FALSE(blit_pass->AddCopy(DeviceBuffer::AsBufferView(src), dst,
105  std::nullopt, "", /*slice=*/25));
106  EXPECT_FALSE(blit_pass->AddCopy(DeviceBuffer::AsBufferView(src), dst,
107  std::nullopt, "", /*slice=*/6));
108  EXPECT_TRUE(blit_pass->AddCopy(DeviceBuffer::AsBufferView(src), dst,
109  std::nullopt, "", /*slice=*/0));
110 }

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() [261/454]

impeller::testing::TEST_P ( ComputeTest  ,
1DThreadgroupSizingIsCorrect   
)

Definition at line 175 of file compute_unittests.cc.

175  {
176  using CS = ThreadgroupSizingTestComputeShader;
177  auto context = GetContext();
178  ASSERT_TRUE(context);
179  ASSERT_TRUE(context->GetCapabilities()->SupportsCompute());
180 
181  using SamplePipelineBuilder = ComputePipelineBuilder<CS>;
182  auto pipeline_desc =
183  SamplePipelineBuilder::MakeDefaultPipelineDescriptor(*context);
184  ASSERT_TRUE(pipeline_desc.has_value());
185  auto compute_pipeline =
186  context->GetPipelineLibrary()->GetPipeline(pipeline_desc).Get();
187  ASSERT_TRUE(compute_pipeline);
188 
189  auto cmd_buffer = context->CreateCommandBuffer();
190  auto pass = cmd_buffer->CreateComputePass();
191  ASSERT_TRUE(pass && pass->IsValid());
192 
193  static constexpr size_t kCount = 2048;
194 
195  pass->SetPipeline(compute_pipeline);
196 
197  auto output_buffer = CreateHostVisibleDeviceBuffer<CS::OutputData<kCount>>(
198  context, "Output Buffer");
199 
200  CS::BindOutputData(*pass, DeviceBuffer::AsBufferView(output_buffer));
201 
202  ASSERT_TRUE(pass->Compute(ISize(kCount, 1)).ok());
203  ASSERT_TRUE(pass->EncodeCommands());
204 
205  fml::AutoResetWaitableEvent latch;
206  ASSERT_TRUE(
207  context->GetCommandQueue()
208  ->Submit({cmd_buffer},
209  [&latch, output_buffer](CommandBuffer::Status status) {
210  EXPECT_EQ(status, CommandBuffer::Status::kCompleted);
211 
212  auto view = DeviceBuffer::AsBufferView(output_buffer);
213  EXPECT_EQ(view.range.length,
214  sizeof(CS::OutputData<kCount>));
215 
216  CS::OutputData<kCount>* output =
217  reinterpret_cast<CS::OutputData<kCount>*>(
218  output_buffer->OnGetContents());
219  EXPECT_TRUE(output);
220  EXPECT_EQ(output->data[kCount - 1], kCount - 1);
221  latch.Signal();
222  })
223  .ok());
224 
225  latch.Wait();
226 }

◆ TEST_P() [262/454]

impeller::testing::TEST_P ( ComputeTest  ,
CanCompute1DimensionalData   
)

Definition at line 373 of file compute_unittests.cc.

373  {
374  using CS = SampleComputeShader;
375  auto context = GetContext();
376  auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
377  ASSERT_TRUE(context);
378  ASSERT_TRUE(context->GetCapabilities()->SupportsCompute());
379 
380  using SamplePipelineBuilder = ComputePipelineBuilder<CS>;
381  auto pipeline_desc =
382  SamplePipelineBuilder::MakeDefaultPipelineDescriptor(*context);
383  ASSERT_TRUE(pipeline_desc.has_value());
384  auto compute_pipeline =
385  context->GetPipelineLibrary()->GetPipeline(pipeline_desc).Get();
386  ASSERT_TRUE(compute_pipeline);
387 
388  auto cmd_buffer = context->CreateCommandBuffer();
389  auto pass = cmd_buffer->CreateComputePass();
390  ASSERT_TRUE(pass && pass->IsValid());
391 
392  static constexpr size_t kCount = 5;
393 
394  pass->SetPipeline(compute_pipeline);
395 
396  CS::Info info{.count = kCount};
397  CS::Input0<kCount> input_0;
398  CS::Input1<kCount> input_1;
399  for (size_t i = 0; i < kCount; i++) {
400  input_0.elements[i] = Vector4(2.0 + i, 3.0 + i, 4.0 + i, 5.0 * i);
401  input_1.elements[i] = Vector4(6.0, 7.0, 8.0, 9.0);
402  }
403 
404  input_0.fixed_array[1] = IPoint32(2, 2);
405  input_1.fixed_array[0] = UintPoint32(3, 3);
406  input_0.some_int = 5;
407  input_1.some_struct = CS::SomeStruct{.vf = Point(3, 4), .i = 42};
408 
409  auto output_buffer = CreateHostVisibleDeviceBuffer<CS::Output<kCount>>(
410  context, "Output Buffer");
411 
412  CS::BindInfo(*pass, host_buffer->EmplaceUniform(info));
413  CS::BindInput0(*pass, host_buffer->EmplaceStorageBuffer(input_0));
414  CS::BindInput1(*pass, host_buffer->EmplaceStorageBuffer(input_1));
415  CS::BindOutput(*pass, DeviceBuffer::AsBufferView(output_buffer));
416 
417  ASSERT_TRUE(pass->Compute(ISize(kCount, 1)).ok());
418  ASSERT_TRUE(pass->EncodeCommands());
419 
420  fml::AutoResetWaitableEvent latch;
421  ASSERT_TRUE(
422  context->GetCommandQueue()
423  ->Submit(
424  {cmd_buffer},
425  [&latch, output_buffer, &input_0,
426  &input_1](CommandBuffer::Status status) {
427  EXPECT_EQ(status, CommandBuffer::Status::kCompleted);
428 
429  auto view = DeviceBuffer::AsBufferView(output_buffer);
430  EXPECT_EQ(view.range.length, sizeof(CS::Output<kCount>));
431 
432  CS::Output<kCount>* output =
433  reinterpret_cast<CS::Output<kCount>*>(
434  output_buffer->OnGetContents());
435  EXPECT_TRUE(output);
436  for (size_t i = 0; i < kCount; i++) {
437  Vector4 vector = output->elements[i];
438  Vector4 computed = input_0.elements[i] * input_1.elements[i];
439  EXPECT_EQ(vector,
440  Vector4(computed.x + 2 + input_1.some_struct.i,
441  computed.y + 3 + input_1.some_struct.vf.x,
442  computed.z + 5 + input_1.some_struct.vf.y,
443  computed.w));
444  }
445  latch.Signal();
446  })
447  .ok());
448 
449  latch.Wait();
450 }

References impeller::interop::Create().

◆ TEST_P() [263/454]

impeller::testing::TEST_P ( ComputeTest  ,
CanComputePrefixSum   
)

Definition at line 109 of file compute_unittests.cc.

109  {
110  using CS = PrefixSumTestComputeShader;
111  auto context = GetContext();
112  auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
113  ASSERT_TRUE(context);
114  ASSERT_TRUE(context->GetCapabilities()->SupportsCompute());
115 
116  using SamplePipelineBuilder = ComputePipelineBuilder<CS>;
117  auto pipeline_desc =
118  SamplePipelineBuilder::MakeDefaultPipelineDescriptor(*context);
119  ASSERT_TRUE(pipeline_desc.has_value());
120  auto compute_pipeline =
121  context->GetPipelineLibrary()->GetPipeline(pipeline_desc).Get();
122  ASSERT_TRUE(compute_pipeline);
123 
124  auto cmd_buffer = context->CreateCommandBuffer();
125  auto pass = cmd_buffer->CreateComputePass();
126  ASSERT_TRUE(pass && pass->IsValid());
127 
128  static constexpr size_t kCount = 5;
129 
130  pass->SetPipeline(compute_pipeline);
131 
132  CS::InputData<kCount> input_data;
133  input_data.count = kCount;
134  for (size_t i = 0; i < kCount; i++) {
135  input_data.data[i] = 1 + i;
136  }
137 
138  auto output_buffer = CreateHostVisibleDeviceBuffer<CS::OutputData<kCount>>(
139  context, "Output Buffer");
140 
141  CS::BindInputData(*pass, host_buffer->EmplaceStorageBuffer(input_data));
142  CS::BindOutputData(*pass, DeviceBuffer::AsBufferView(output_buffer));
143 
144  ASSERT_TRUE(pass->Compute(ISize(kCount, 1)).ok());
145  ASSERT_TRUE(pass->EncodeCommands());
146 
147  fml::AutoResetWaitableEvent latch;
148  ASSERT_TRUE(
149  context->GetCommandQueue()
150  ->Submit({cmd_buffer},
151  [&latch, output_buffer](CommandBuffer::Status status) {
152  EXPECT_EQ(status, CommandBuffer::Status::kCompleted);
153 
154  auto view = DeviceBuffer::AsBufferView(output_buffer);
155  EXPECT_EQ(view.range.length,
156  sizeof(CS::OutputData<kCount>));
157 
158  CS::OutputData<kCount>* output =
159  reinterpret_cast<CS::OutputData<kCount>*>(
160  output_buffer->OnGetContents());
161  EXPECT_TRUE(output);
162 
163  constexpr uint32_t expected[kCount] = {1, 3, 6, 10, 15};
164  for (size_t i = 0; i < kCount; i++) {
165  auto computed_sum = output->data[i];
166  EXPECT_EQ(computed_sum, expected[i]);
167  }
168  latch.Signal();
169  })
170  .ok());
171 
172  latch.Wait();
173 }

References impeller::DeviceBuffer::AsBufferView(), and impeller::HostBuffer::Create().

◆ TEST_P() [264/454]

impeller::testing::TEST_P ( ComputeTest  ,
CanComputePrefixSumLargeInteractive   
)

Definition at line 228 of file compute_unittests.cc.

228  {
229  using CS = PrefixSumTestComputeShader;
230 
231  auto context = GetContext();
232  auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
233 
234  ASSERT_TRUE(context);
235  ASSERT_TRUE(context->GetCapabilities()->SupportsCompute());
236 
237  auto callback = [&](RenderPass& render_pass) -> bool {
238  using SamplePipelineBuilder = ComputePipelineBuilder<CS>;
239  auto pipeline_desc =
240  SamplePipelineBuilder::MakeDefaultPipelineDescriptor(*context);
241  auto compute_pipeline =
242  context->GetPipelineLibrary()->GetPipeline(pipeline_desc).Get();
243 
244  auto cmd_buffer = context->CreateCommandBuffer();
245  auto pass = cmd_buffer->CreateComputePass();
246 
247  static constexpr size_t kCount = 1023;
248 
249  pass->SetPipeline(compute_pipeline);
250 
251  CS::InputData<kCount> input_data;
252  input_data.count = kCount;
253  for (size_t i = 0; i < kCount; i++) {
254  input_data.data[i] = 1 + i;
255  }
256 
257  auto output_buffer = CreateHostVisibleDeviceBuffer<CS::OutputData<kCount>>(
258  context, "Output Buffer");
259 
260  CS::BindInputData(*pass, host_buffer->EmplaceStorageBuffer(input_data));
261  CS::BindOutputData(*pass, DeviceBuffer::AsBufferView(output_buffer));
262 
263  pass->Compute(ISize(kCount, 1));
264  pass->EncodeCommands();
265  host_buffer->Reset();
266  return context->GetCommandQueue()->Submit({cmd_buffer}).ok();
267  };
268  ASSERT_TRUE(OpenPlaygroundHere(callback));
269 }

References impeller::interop::Create().

◆ TEST_P() [265/454]

impeller::testing::TEST_P ( ComputeTest  ,
CanCreateComputePass   
)

Definition at line 30 of file compute_unittests.cc.

30  {
31  using CS = SampleComputeShader;
32  auto context = GetContext();
33  auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
34  ASSERT_TRUE(context);
35  ASSERT_TRUE(context->GetCapabilities()->SupportsCompute());
36 
37  using SamplePipelineBuilder = ComputePipelineBuilder<CS>;
38  auto pipeline_desc =
39  SamplePipelineBuilder::MakeDefaultPipelineDescriptor(*context);
40  ASSERT_TRUE(pipeline_desc.has_value());
41  auto compute_pipeline =
42  context->GetPipelineLibrary()->GetPipeline(pipeline_desc).Get();
43  ASSERT_TRUE(compute_pipeline);
44 
45  auto cmd_buffer = context->CreateCommandBuffer();
46  auto pass = cmd_buffer->CreateComputePass();
47  ASSERT_TRUE(pass && pass->IsValid());
48 
49  static constexpr size_t kCount = 5;
50 
51  pass->SetPipeline(compute_pipeline);
52 
53  CS::Info info{.count = kCount};
54  CS::Input0<kCount> input_0;
55  CS::Input1<kCount> input_1;
56  for (size_t i = 0; i < kCount; i++) {
57  input_0.elements[i] = Vector4(2.0 + i, 3.0 + i, 4.0 + i, 5.0 * i);
58  input_1.elements[i] = Vector4(6.0, 7.0, 8.0, 9.0);
59  }
60 
61  input_0.fixed_array[1] = IPoint32(2, 2);
62  input_1.fixed_array[0] = UintPoint32(3, 3);
63  input_0.some_int = 5;
64  input_1.some_struct = CS::SomeStruct{.vf = Point(3, 4), .i = 42};
65 
66  auto output_buffer = CreateHostVisibleDeviceBuffer<CS::Output<kCount>>(
67  context, "Output Buffer");
68 
69  CS::BindInfo(*pass, host_buffer->EmplaceUniform(info));
70  CS::BindInput0(*pass, host_buffer->EmplaceStorageBuffer(input_0));
71  CS::BindInput1(*pass, host_buffer->EmplaceStorageBuffer(input_1));
72  CS::BindOutput(*pass, DeviceBuffer::AsBufferView(output_buffer));
73 
74  ASSERT_TRUE(pass->Compute(ISize(kCount, 1)).ok());
75  ASSERT_TRUE(pass->EncodeCommands());
76 
77  fml::AutoResetWaitableEvent latch;
78  ASSERT_TRUE(
79  context->GetCommandQueue()
80  ->Submit(
81  {cmd_buffer},
82  [&latch, output_buffer, &input_0,
83  &input_1](CommandBuffer::Status status) {
84  EXPECT_EQ(status, CommandBuffer::Status::kCompleted);
85 
86  auto view = DeviceBuffer::AsBufferView(output_buffer);
87  EXPECT_EQ(view.range.length, sizeof(CS::Output<kCount>));
88 
89  CS::Output<kCount>* output =
90  reinterpret_cast<CS::Output<kCount>*>(
91  output_buffer->OnGetContents());
92  EXPECT_TRUE(output);
93  for (size_t i = 0; i < kCount; i++) {
94  Vector4 vector = output->elements[i];
95  Vector4 computed = input_0.elements[i] * input_1.elements[i];
96  EXPECT_EQ(vector,
97  Vector4(computed.x + 2 + input_1.some_struct.i,
98  computed.y + 3 + input_1.some_struct.vf.x,
99  computed.z + 5 + input_1.some_struct.vf.y,
100  computed.w));
101  }
102  latch.Signal();
103  })
104  .ok());
105 
106  latch.Wait();
107 }

References impeller::DeviceBuffer::AsBufferView(), and impeller::HostBuffer::Create().

◆ TEST_P() [266/454]

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() [267/454]

impeller::testing::TEST_P ( ComputeTest  ,
MultiStageInputAndOutput   
)

Definition at line 271 of file compute_unittests.cc.

271  {
272  using CS1 = Stage1ComputeShader;
273  using Stage1PipelineBuilder = ComputePipelineBuilder<CS1>;
274  using CS2 = Stage2ComputeShader;
275  using Stage2PipelineBuilder = ComputePipelineBuilder<CS2>;
276 
277  auto context = GetContext();
278  auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
279  ASSERT_TRUE(context);
280  ASSERT_TRUE(context->GetCapabilities()->SupportsCompute());
281 
282  auto pipeline_desc_1 =
283  Stage1PipelineBuilder::MakeDefaultPipelineDescriptor(*context);
284  ASSERT_TRUE(pipeline_desc_1.has_value());
285  auto compute_pipeline_1 =
286  context->GetPipelineLibrary()->GetPipeline(pipeline_desc_1).Get();
287  ASSERT_TRUE(compute_pipeline_1);
288 
289  auto pipeline_desc_2 =
290  Stage2PipelineBuilder::MakeDefaultPipelineDescriptor(*context);
291  ASSERT_TRUE(pipeline_desc_2.has_value());
292  auto compute_pipeline_2 =
293  context->GetPipelineLibrary()->GetPipeline(pipeline_desc_2).Get();
294  ASSERT_TRUE(compute_pipeline_2);
295 
296  auto cmd_buffer = context->CreateCommandBuffer();
297  auto pass = cmd_buffer->CreateComputePass();
298  ASSERT_TRUE(pass && pass->IsValid());
299 
300  static constexpr size_t kCount1 = 5;
301  static constexpr size_t kCount2 = kCount1 * 2;
302 
303  CS1::Input<kCount1> input_1;
304  input_1.count = kCount1;
305  for (size_t i = 0; i < kCount1; i++) {
306  input_1.elements[i] = i;
307  }
308 
309  CS2::Input<kCount2> input_2;
310  input_2.count = kCount2;
311  for (size_t i = 0; i < kCount2; i++) {
312  input_2.elements[i] = i;
313  }
314 
315  auto output_buffer_1 = CreateHostVisibleDeviceBuffer<CS1::Output<kCount2>>(
316  context, "Output Buffer Stage 1");
317  auto output_buffer_2 = CreateHostVisibleDeviceBuffer<CS2::Output<kCount2>>(
318  context, "Output Buffer Stage 2");
319 
320  {
321  pass->SetPipeline(compute_pipeline_1);
322 
323  CS1::BindInput(*pass, host_buffer->EmplaceStorageBuffer(input_1));
324  CS1::BindOutput(*pass, DeviceBuffer::AsBufferView(output_buffer_1));
325 
326  ASSERT_TRUE(pass->Compute(ISize(512, 1)).ok());
327  pass->AddBufferMemoryBarrier();
328  }
329 
330  {
331  pass->SetPipeline(compute_pipeline_2);
332 
333  CS1::BindInput(*pass, DeviceBuffer::AsBufferView(output_buffer_1));
334  CS2::BindOutput(*pass, DeviceBuffer::AsBufferView(output_buffer_2));
335  ASSERT_TRUE(pass->Compute(ISize(512, 1)).ok());
336  }
337 
338  ASSERT_TRUE(pass->EncodeCommands());
339 
340  fml::AutoResetWaitableEvent latch;
341  ASSERT_TRUE(
342  context->GetCommandQueue()
343  ->Submit({cmd_buffer},
344  [&latch, &output_buffer_1,
345  &output_buffer_2](CommandBuffer::Status status) {
346  EXPECT_EQ(status, CommandBuffer::Status::kCompleted);
347 
348  CS1::Output<kCount2>* output_1 =
349  reinterpret_cast<CS1::Output<kCount2>*>(
350  output_buffer_1->OnGetContents());
351  EXPECT_TRUE(output_1);
352  EXPECT_EQ(output_1->count, 10u);
353  EXPECT_THAT(
354  output_1->elements,
355  ::testing::ElementsAre(0, 0, 2, 3, 4, 6, 6, 9, 8, 12));
356 
357  CS2::Output<kCount2>* output_2 =
358  reinterpret_cast<CS2::Output<kCount2>*>(
359  output_buffer_2->OnGetContents());
360  EXPECT_TRUE(output_2);
361  EXPECT_EQ(output_2->count, 10u);
362  EXPECT_THAT(output_2->elements,
363  ::testing::ElementsAre(0, 0, 4, 6, 8, 12, 12,
364  18, 16, 24));
365 
366  latch.Signal();
367  })
368  .ok());
369 
370  latch.Wait();
371 }

References impeller::interop::Create(), and impeller::kCount1.

◆ TEST_P() [268/454]

impeller::testing::TEST_P ( ComputeTest  ,
ReturnsEarlyWhenAnyGridDimensionIsZero   
)

Definition at line 452 of file compute_unittests.cc.

452  {
453  using CS = SampleComputeShader;
454  auto context = GetContext();
455  auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
456  ASSERT_TRUE(context);
457  ASSERT_TRUE(context->GetCapabilities()->SupportsCompute());
458 
459  using SamplePipelineBuilder = ComputePipelineBuilder<CS>;
460  auto pipeline_desc =
461  SamplePipelineBuilder::MakeDefaultPipelineDescriptor(*context);
462  ASSERT_TRUE(pipeline_desc.has_value());
463  auto compute_pipeline =
464  context->GetPipelineLibrary()->GetPipeline(pipeline_desc).Get();
465  ASSERT_TRUE(compute_pipeline);
466 
467  auto cmd_buffer = context->CreateCommandBuffer();
468  auto pass = cmd_buffer->CreateComputePass();
469  ASSERT_TRUE(pass && pass->IsValid());
470 
471  static constexpr size_t kCount = 5;
472 
473  pass->SetPipeline(compute_pipeline);
474 
475  CS::Info info{.count = kCount};
476  CS::Input0<kCount> input_0;
477  CS::Input1<kCount> input_1;
478  for (size_t i = 0; i < kCount; i++) {
479  input_0.elements[i] = Vector4(2.0 + i, 3.0 + i, 4.0 + i, 5.0 * i);
480  input_1.elements[i] = Vector4(6.0, 7.0, 8.0, 9.0);
481  }
482 
483  input_0.fixed_array[1] = IPoint32(2, 2);
484  input_1.fixed_array[0] = UintPoint32(3, 3);
485  input_0.some_int = 5;
486  input_1.some_struct = CS::SomeStruct{.vf = Point(3, 4), .i = 42};
487 
488  auto output_buffer = CreateHostVisibleDeviceBuffer<CS::Output<kCount>>(
489  context, "Output Buffer");
490 
491  CS::BindInfo(*pass, host_buffer->EmplaceUniform(info));
492  CS::BindInput0(*pass, host_buffer->EmplaceStorageBuffer(input_0));
493  CS::BindInput1(*pass, host_buffer->EmplaceStorageBuffer(input_1));
494  CS::BindOutput(*pass, DeviceBuffer::AsBufferView(output_buffer));
495 
496  // Intentionally making the grid size zero in one dimension. No GPU will
497  // tolerate this.
498  EXPECT_FALSE(pass->Compute(ISize(0, 1)).ok());
499  pass->EncodeCommands();
500 }

References impeller::interop::Create().

◆ TEST_P() [269/454]

impeller::testing::TEST_P ( DisplayListTest  ,
CanBlendDstOverAndDstCorrectly   
)

Definition at line 1175 of file dl_unittests.cc.

1175  {
1176  flutter::DisplayListBuilder builder;
1177 
1178  {
1179  builder.SaveLayer(nullptr, nullptr);
1180  builder.Translate(100, 100);
1181  flutter::DlPaint paint;
1182  paint.setColor(flutter::DlColor::kRed());
1183  builder.DrawRect(SkRect::MakeSize({200, 200}), paint);
1184  paint.setColor(flutter::DlColor::kBlue().withAlpha(127));
1185  paint.setBlendMode(flutter::DlBlendMode::kSrcOver);
1186  builder.DrawRect(SkRect::MakeSize({200, 200}), paint);
1187  builder.Restore();
1188  }
1189  {
1190  builder.SaveLayer(nullptr, nullptr);
1191  builder.Translate(300, 100);
1192  flutter::DlPaint paint;
1193  paint.setColor(flutter::DlColor::kBlue().withAlpha(127));
1194  builder.DrawRect(SkRect::MakeSize({200, 200}), paint);
1195  paint.setColor(flutter::DlColor::kRed());
1196  paint.setBlendMode(flutter::DlBlendMode::kDstOver);
1197  builder.DrawRect(SkRect::MakeSize({200, 200}), paint);
1198  builder.Restore();
1199  }
1200  {
1201  builder.SaveLayer(nullptr, nullptr);
1202  builder.Translate(100, 300);
1203  flutter::DlPaint paint;
1204  paint.setColor(flutter::DlColor::kRed());
1205  builder.DrawRect(SkRect::MakeSize({200, 200}), paint);
1206  paint.setColor(flutter::DlColor::kBlue().withAlpha(127));
1207  paint.setBlendMode(flutter::DlBlendMode::kSrc);
1208  builder.DrawRect(SkRect::MakeSize({200, 200}), paint);
1209  builder.Restore();
1210  }
1211  {
1212  builder.SaveLayer(nullptr, nullptr);
1213  builder.Translate(300, 300);
1214  flutter::DlPaint paint;
1215  paint.setColor(flutter::DlColor::kBlue().withAlpha(127));
1216  builder.DrawRect(SkRect::MakeSize({200, 200}), paint);
1217  paint.setColor(flutter::DlColor::kRed());
1218  paint.setBlendMode(flutter::DlBlendMode::kDst);
1219  builder.DrawRect(SkRect::MakeSize({200, 200}), paint);
1220  builder.Restore();
1221  }
1222 
1223  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1224 }

◆ TEST_P() [270/454]

impeller::testing::TEST_P ( DisplayListTest  ,
CanClampTheResultingColorOfColorMatrixFilter   
)

Definition at line 616 of file dl_unittests.cc.

616  {
617  auto texture = CreateTextureForFixture("boston.jpg");
618  const float inner_color_matrix[20] = {
619  1, 0, 0, 0, 0, //
620  0, 1, 0, 0, 0, //
621  0, 0, 1, 0, 0, //
622  0, 0, 0, 2, 0, //
623  };
624  const float outer_color_matrix[20] = {
625  1, 0, 0, 0, 0, //
626  0, 1, 0, 0, 0, //
627  0, 0, 1, 0, 0, //
628  0, 0, 0, 0.5, 0, //
629  };
630  auto inner_color_filter =
631  std::make_shared<flutter::DlMatrixColorFilter>(inner_color_matrix);
632  auto outer_color_filter =
633  std::make_shared<flutter::DlMatrixColorFilter>(outer_color_matrix);
634  auto inner =
635  std::make_shared<flutter::DlColorFilterImageFilter>(inner_color_filter);
636  auto outer =
637  std::make_shared<flutter::DlColorFilterImageFilter>(outer_color_filter);
638  auto compose = std::make_shared<flutter::DlComposeImageFilter>(outer, inner);
639 
640  flutter::DisplayListBuilder builder;
641  flutter::DlPaint paint;
642  paint.setImageFilter(compose.get());
643  builder.DrawImage(DlImageImpeller::Make(texture), SkPoint::Make(100, 100),
644  flutter::DlImageSampling::kNearestNeighbor, &paint);
645  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
646 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [271/454]

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() [272/454]

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() [273/454]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawBackdropFilter   
)

Definition at line 648 of file dl_unittests.cc.

648  {
649  auto texture = CreateTextureForFixture("embarcadero.jpg");
650 
651  auto callback = [&]() {
652  static float sigma[] = {10, 10};
653  static float ctm_scale = 1;
654  static bool use_bounds = true;
655  static bool draw_circle = true;
656  static bool add_clip = true;
657 
658  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
659  ImGui::SliderFloat2("Sigma", sigma, 0, 100);
660  ImGui::SliderFloat("Scale", &ctm_scale, 0, 10);
661  ImGui::NewLine();
662  ImGui::TextWrapped(
663  "If everything is working correctly, none of the options below should "
664  "impact the filter's appearance.");
665  ImGui::Checkbox("Use SaveLayer bounds", &use_bounds);
666  ImGui::Checkbox("Draw child element", &draw_circle);
667  ImGui::Checkbox("Add pre-clip", &add_clip);
668  ImGui::End();
669 
670  flutter::DisplayListBuilder builder;
671 
672  Vector2 scale = ctm_scale * GetContentScale();
673  builder.Scale(scale.x, scale.y);
674 
675  auto filter = flutter::DlBlurImageFilter(sigma[0], sigma[1],
676  flutter::DlTileMode::kClamp);
677 
678  std::optional<SkRect> bounds;
679  if (use_bounds) {
680  static PlaygroundPoint point_a(Point(350, 150), 20, Color::White());
681  static PlaygroundPoint point_b(Point(800, 600), 20, Color::White());
682  auto [p1, p2] = DrawPlaygroundLine(point_a, point_b);
683  bounds = SkRect::MakeLTRB(p1.x, p1.y, p2.x, p2.y);
684  }
685 
686  // Insert a clip to test that the backdrop filter handles stencil depths > 0
687  // correctly.
688  if (add_clip) {
689  builder.ClipRect(SkRect::MakeLTRB(0, 0, 99999, 99999),
690  flutter::DlCanvas::ClipOp::kIntersect, true);
691  }
692 
693  builder.DrawImage(DlImageImpeller::Make(texture), SkPoint::Make(200, 200),
694  flutter::DlImageSampling::kNearestNeighbor, nullptr);
695  builder.SaveLayer(bounds.has_value() ? &bounds.value() : nullptr, nullptr,
696  &filter);
697 
698  if (draw_circle) {
699  static PlaygroundPoint center_point(Point(500, 400), 20, Color::Red());
700  auto circle_center = DrawPlaygroundPoint(center_point);
701 
702  flutter::DlPaint paint;
703  paint.setDrawStyle(flutter::DlDrawStyle::kStroke);
704  paint.setStrokeCap(flutter::DlStrokeCap::kButt);
705  paint.setStrokeJoin(flutter::DlStrokeJoin::kBevel);
706  paint.setStrokeWidth(10);
707  paint.setColor(flutter::DlColor::kRed().withAlpha(100));
708  builder.DrawCircle({circle_center.x, circle_center.y}, 100, paint);
709  }
710 
711  return builder.Build();
712  };
713 
714  ASSERT_TRUE(OpenPlaygroundHere(callback));
715 }

References impeller::DrawPlaygroundLine(), impeller::DrawPlaygroundPoint(), impeller::DlImageImpeller::Make(), impeller::Color::Red(), scale, and impeller::Color::White().

◆ TEST_P() [274/454]

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() [275/454]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawCorrectlyWithColorFilterAndImageFilter   
)

Definition at line 1226 of file dl_unittests.cc.

1226  {
1227  flutter::DisplayListBuilder builder;
1228  const float green_color_matrix[20] = {
1229  0, 0, 0, 0, 0, //
1230  0, 0, 0, 0, 1, //
1231  0, 0, 0, 0, 0, //
1232  0, 0, 0, 1, 0, //
1233  };
1234  const float blue_color_matrix[20] = {
1235  0, 0, 0, 0, 0, //
1236  0, 0, 0, 0, 0, //
1237  0, 0, 0, 0, 1, //
1238  0, 0, 0, 1, 0, //
1239  };
1240  auto green_color_filter =
1241  std::make_shared<flutter::DlMatrixColorFilter>(green_color_matrix);
1242  auto blue_color_filter =
1243  std::make_shared<flutter::DlMatrixColorFilter>(blue_color_matrix);
1244  auto blue_image_filter =
1245  std::make_shared<flutter::DlColorFilterImageFilter>(blue_color_filter);
1246 
1247  flutter::DlPaint paint;
1248  paint.setColor(flutter::DlColor::kRed());
1249  paint.setColorFilter(green_color_filter);
1250  paint.setImageFilter(blue_image_filter);
1251  builder.DrawRect(SkRect::MakeLTRB(100, 100, 500, 500), paint);
1252  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1253 }

◆ TEST_P() [276/454]

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() [277/454]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawNinePatchImage   
)

Definition at line 717 of file dl_unittests.cc.

717  {
718  // Image is drawn with corners to scale and center pieces stretched to fit.
719  auto texture = CreateTextureForFixture("embarcadero.jpg");
720  flutter::DisplayListBuilder builder;
721  auto size = texture->GetSize();
722  builder.DrawImageNine(
723  DlImageImpeller::Make(texture),
724  SkIRect::MakeLTRB(size.width / 4, size.height / 4, size.width * 3 / 4,
725  size.height * 3 / 4),
726  SkRect::MakeLTRB(0, 0, size.width * 2, size.height * 2),
727  flutter::DlFilterMode::kNearest, nullptr);
728  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
729 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [278/454]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawNinePatchImageCenterBiggerThanDest   
)

Definition at line 763 of file dl_unittests.cc.

763  {
764  // Edge case, the width and height of the corners does not leave any
765  // room for the center slices. Only the corners are displayed.
766  auto texture = CreateTextureForFixture("embarcadero.jpg");
767  flutter::DisplayListBuilder builder;
768  auto size = texture->GetSize();
769  builder.DrawImageNine(
770  DlImageImpeller::Make(texture),
771  SkIRect::MakeLTRB(size.width / 4, size.height / 4, size.width * 3 / 4,
772  size.height * 3 / 4),
773  SkRect::MakeLTRB(0, 0, size.width / 2, size.height / 2),
774  flutter::DlFilterMode::kNearest, nullptr);
775  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
776 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [279/454]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawNinePatchImageCenterHeightBiggerThanDest   
)

Definition at line 747 of file dl_unittests.cc.

747  {
748  // Edge case, the height of the corners does not leave any room for the
749  // center slice. The center (across the horizontal axis) is folded out of the
750  // resulting image.
751  auto texture = CreateTextureForFixture("embarcadero.jpg");
752  flutter::DisplayListBuilder builder;
753  auto size = texture->GetSize();
754  builder.DrawImageNine(
755  DlImageImpeller::Make(texture),
756  SkIRect::MakeLTRB(size.width / 4, size.height / 4, size.width * 3 / 4,
757  size.height * 3 / 4),
758  SkRect::MakeLTRB(0, 0, size.width, size.height / 2),
759  flutter::DlFilterMode::kNearest, nullptr);
760  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
761 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [280/454]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawNinePatchImageCenterWidthBiggerThanDest   
)

Definition at line 731 of file dl_unittests.cc.

731  {
732  // Edge case, the width of the corners does not leave any room for the
733  // center slice. The center (across the vertical axis) is folded out of the
734  // resulting image.
735  auto texture = CreateTextureForFixture("embarcadero.jpg");
736  flutter::DisplayListBuilder builder;
737  auto size = texture->GetSize();
738  builder.DrawImageNine(
739  DlImageImpeller::Make(texture),
740  SkIRect::MakeLTRB(size.width / 4, size.height / 4, size.width * 3 / 4,
741  size.height * 3 / 4),
742  SkRect::MakeLTRB(0, 0, size.width / 2, size.height),
743  flutter::DlFilterMode::kNearest, nullptr);
744  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
745 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [281/454]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawNinePatchImageCornersScaledDown   
)

Definition at line 778 of file dl_unittests.cc.

778  {
779  // Edge case, there is not enough room for the corners to be drawn
780  // without scaling them down.
781  auto texture = CreateTextureForFixture("embarcadero.jpg");
782  flutter::DisplayListBuilder builder;
783  auto size = texture->GetSize();
784  builder.DrawImageNine(
785  DlImageImpeller::Make(texture),
786  SkIRect::MakeLTRB(size.width / 4, size.height / 4, size.width * 3 / 4,
787  size.height * 3 / 4),
788  SkRect::MakeLTRB(0, 0, size.width / 4, size.height / 4),
789  flutter::DlFilterMode::kNearest, nullptr);
790  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
791 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [282/454]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawPaintWithColorSource   
)

Definition at line 1123 of file dl_unittests.cc.

1123  {
1124  const flutter::DlColor colors[2] = {
1125  flutter::DlColor(0xFFF44336),
1126  flutter::DlColor(0xFF2196F3),
1127  };
1128  const float stops[2] = {0.0, 1.0};
1129  flutter::DlPaint paint;
1130  flutter::DisplayListBuilder builder;
1131  auto clip_bounds = SkRect::MakeWH(300.0, 300.0);
1132  builder.Save();
1133  builder.Translate(100, 100);
1134  builder.ClipRect(clip_bounds, flutter::DlCanvas::ClipOp::kIntersect, false);
1135  auto linear =
1136  flutter::DlColorSource::MakeLinear({0.0, 0.0}, {100.0, 100.0}, 2, colors,
1137  stops, flutter::DlTileMode::kRepeat);
1138  paint.setColorSource(linear);
1139  builder.DrawPaint(paint);
1140  builder.Restore();
1141 
1142  builder.Save();
1143  builder.Translate(500, 100);
1144  builder.ClipRect(clip_bounds, flutter::DlCanvas::ClipOp::kIntersect, false);
1145  auto radial = flutter::DlColorSource::MakeRadial(
1146  {100.0, 100.0}, 100.0, 2, colors, stops, flutter::DlTileMode::kRepeat);
1147  paint.setColorSource(radial);
1148  builder.DrawPaint(paint);
1149  builder.Restore();
1150 
1151  builder.Save();
1152  builder.Translate(100, 500);
1153  builder.ClipRect(clip_bounds, flutter::DlCanvas::ClipOp::kIntersect, false);
1154  auto sweep =
1155  flutter::DlColorSource::MakeSweep({100.0, 100.0}, 180.0, 270.0, 2, colors,
1156  stops, flutter::DlTileMode::kRepeat);
1157  paint.setColorSource(sweep);
1158  builder.DrawPaint(paint);
1159  builder.Restore();
1160 
1161  builder.Save();
1162  builder.Translate(500, 500);
1163  builder.ClipRect(clip_bounds, flutter::DlCanvas::ClipOp::kIntersect, false);
1164  auto texture = CreateTextureForFixture("table_mountain_nx.png");
1165  auto image = std::make_shared<flutter::DlImageColorSource>(
1166  DlImageImpeller::Make(texture), flutter::DlTileMode::kRepeat,
1167  flutter::DlTileMode::kRepeat);
1168  paint.setColorSource(image);
1169  builder.DrawPaint(paint);
1170  builder.Restore();
1171 
1172  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1173 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [283/454]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawPoints   
)

Definition at line 805 of file dl_unittests.cc.

805  {
806  flutter::DisplayListBuilder builder;
807  SkPoint points[7] = {
808  {0, 0}, //
809  {100, 100}, //
810  {100, 0}, //
811  {0, 100}, //
812  {0, 0}, //
813  {48, 48}, //
814  {52, 52}, //
815  };
816  std::vector<flutter::DlStrokeCap> caps = {
817  flutter::DlStrokeCap::kButt,
818  flutter::DlStrokeCap::kRound,
819  flutter::DlStrokeCap::kSquare,
820  };
821  flutter::DlPaint paint =
822  flutter::DlPaint() //
823  .setColor(flutter::DlColor::kYellow().withAlpha(127)) //
824  .setStrokeWidth(20);
825  builder.Translate(50, 50);
826  for (auto cap : caps) {
827  paint.setStrokeCap(cap);
828  builder.Save();
829  builder.DrawPoints(flutter::DlCanvas::PointMode::kPoints, 7, points, paint);
830  builder.Translate(150, 0);
831  builder.DrawPoints(flutter::DlCanvas::PointMode::kLines, 5, points, paint);
832  builder.Translate(150, 0);
833  builder.DrawPoints(flutter::DlCanvas::PointMode::kPolygon, 5, points,
834  paint);
835  builder.Restore();
836  builder.Translate(0, 150);
837  }
838  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
839 }

◆ TEST_P() [284/454]

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() [285/454]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawRectWithLinearToSrgbColorFilter   
)

Definition at line 1107 of file dl_unittests.cc.

1107  {
1108  flutter::DlPaint paint;
1109  paint.setColor(flutter::DlColor(0xFF2196F3).withAlpha(128));
1110  flutter::DisplayListBuilder builder;
1111  paint.setColorFilter(
1112  flutter::DlLinearToSrgbGammaColorFilter::kInstance.get());
1113  builder.DrawRect(SkRect::MakeXYWH(0, 0, 200, 200), paint);
1114  builder.Translate(0, 200);
1115 
1116  paint.setColorFilter(
1117  flutter::DlSrgbToLinearGammaColorFilter::kInstance.get());
1118  builder.DrawRect(SkRect::MakeXYWH(0, 0, 200, 200), paint);
1119 
1120  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1121 }

◆ TEST_P() [286/454]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawShadow   
)

Definition at line 864 of file dl_unittests.cc.

864  {
865  flutter::DisplayListBuilder builder;
866  flutter::DlPaint paint;
867 
868  auto content_scale = GetContentScale() * 0.8;
869  builder.Scale(content_scale.x, content_scale.y);
870 
871  constexpr size_t star_spikes = 5;
872  constexpr SkScalar half_spike_rotation = kPi / star_spikes;
873  constexpr SkScalar radius = 40;
874  constexpr SkScalar spike_size = 10;
875  constexpr SkScalar outer_radius = radius + spike_size;
876  constexpr SkScalar inner_radius = radius - spike_size;
877  std::array<SkPoint, star_spikes * 2> star;
878  for (size_t i = 0; i < star_spikes; i++) {
879  const SkScalar rotation = half_spike_rotation * i * 2;
880  star[i * 2] = SkPoint::Make(50 + std::sin(rotation) * outer_radius,
881  50 - std::cos(rotation) * outer_radius);
882  star[i * 2 + 1] = SkPoint::Make(
883  50 + std::sin(rotation + half_spike_rotation) * inner_radius,
884  50 - std::cos(rotation + half_spike_rotation) * inner_radius);
885  }
886 
887  std::array<SkPath, 4> paths = {
888  SkPath{}.addRect(SkRect::MakeXYWH(0, 0, 200, 100)),
889  SkPath{}.addRRect(
890  SkRRect::MakeRectXY(SkRect::MakeXYWH(20, 0, 200, 100), 30, 30)),
891  SkPath{}.addCircle(100, 50, 50),
892  SkPath{}.addPoly(star.data(), star.size(), true),
893  };
894  paint.setColor(flutter::DlColor::kWhite());
895  builder.DrawPaint(paint);
896  paint.setColor(flutter::DlColor::kCyan());
897  builder.Translate(100, 50);
898  for (size_t x = 0; x < paths.size(); x++) {
899  builder.Save();
900  for (size_t y = 0; y < 6; y++) {
901  builder.DrawShadow(paths[x], flutter::DlColor::kBlack(), 3 + y * 8, false,
902  1);
903  builder.DrawPath(paths[x], paint);
904  builder.Translate(0, 150);
905  }
906  builder.Restore();
907  builder.Translate(250, 0);
908  }
909 
910  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
911 }

References impeller::kPi.

◆ TEST_P() [287/454]

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() [288/454]

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() [289/454]

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() [290/454]

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() [291/454]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawWithBlendColorFilter   
)

Definition at line 518 of file dl_unittests.cc.

518  {
519  auto texture = CreateTextureForFixture("embarcadero.jpg");
520  flutter::DisplayListBuilder builder;
521  flutter::DlPaint paint;
522 
523  // Pipeline blended image.
524  {
525  auto filter = flutter::DlBlendColorFilter(flutter::DlColor::kYellow(),
526  flutter::DlBlendMode::kModulate);
527  paint.setColorFilter(&filter);
528  builder.DrawImage(DlImageImpeller::Make(texture), SkPoint::Make(100, 100),
529  flutter::DlImageSampling::kNearestNeighbor, &paint);
530  }
531 
532  // Advanced blended image.
533  {
534  auto filter = flutter::DlBlendColorFilter(flutter::DlColor::kRed(),
535  flutter::DlBlendMode::kScreen);
536  paint.setColorFilter(&filter);
537  builder.DrawImage(DlImageImpeller::Make(texture), SkPoint::Make(250, 250),
538  flutter::DlImageSampling::kNearestNeighbor, &paint);
539  }
540 
541  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
542 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [292/454]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawWithColorFilterImageFilter   
)

Definition at line 544 of file dl_unittests.cc.

544  {
545  const float invert_color_matrix[20] = {
546  -1, 0, 0, 0, 1, //
547  0, -1, 0, 0, 1, //
548  0, 0, -1, 0, 1, //
549  0, 0, 0, 1, 0, //
550  };
551  auto texture = CreateTextureForFixture("boston.jpg");
552  flutter::DisplayListBuilder builder;
553  flutter::DlPaint paint;
554 
555  auto color_filter =
556  std::make_shared<flutter::DlMatrixColorFilter>(invert_color_matrix);
557  auto image_filter =
558  std::make_shared<flutter::DlColorFilterImageFilter>(color_filter);
559 
560  paint.setImageFilter(image_filter.get());
561  builder.DrawImage(DlImageImpeller::Make(texture), SkPoint::Make(100, 100),
562  flutter::DlImageSampling::kNearestNeighbor, &paint);
563 
564  builder.Translate(0, 700);
565  paint.setColorFilter(color_filter.get());
566  builder.DrawImage(DlImageImpeller::Make(texture), SkPoint::Make(100, 100),
567  flutter::DlImageSampling::kNearestNeighbor, &paint);
568  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
569 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [293/454]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawWithComposeImageFilter   
)

Definition at line 596 of file dl_unittests.cc.

596  {
597  auto texture = CreateTextureForFixture("boston.jpg");
598  flutter::DisplayListBuilder builder;
599  flutter::DlPaint paint;
600 
601  auto dilate = std::make_shared<flutter::DlDilateImageFilter>(10.0, 10.0);
602  auto erode = std::make_shared<flutter::DlErodeImageFilter>(10.0, 10.0);
603  auto open = std::make_shared<flutter::DlComposeImageFilter>(dilate, erode);
604  auto close = std::make_shared<flutter::DlComposeImageFilter>(erode, dilate);
605 
606  paint.setImageFilter(open.get());
607  builder.DrawImage(DlImageImpeller::Make(texture), SkPoint::Make(100, 100),
608  flutter::DlImageSampling::kNearestNeighbor, &paint);
609  builder.Translate(0, 700);
610  paint.setImageFilter(close.get());
611  builder.DrawImage(DlImageImpeller::Make(texture), SkPoint::Make(100, 100),
612  flutter::DlImageSampling::kNearestNeighbor, &paint);
613  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
614 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [294/454]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawWithImageBlurFilter   
)

Definition at line 571 of file dl_unittests.cc.

571  {
572  auto texture = CreateTextureForFixture("embarcadero.jpg");
573 
574  auto callback = [&]() {
575  static float sigma[] = {10, 10};
576 
577  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
578  ImGui::SliderFloat2("Sigma", sigma, 0, 100);
579  ImGui::End();
580 
581  flutter::DisplayListBuilder builder;
582  flutter::DlPaint paint;
583 
584  auto filter = flutter::DlBlurImageFilter(sigma[0], sigma[1],
585  flutter::DlTileMode::kClamp);
586  paint.setImageFilter(&filter);
587  builder.DrawImage(DlImageImpeller::Make(texture), SkPoint::Make(200, 200),
588  flutter::DlImageSampling::kNearestNeighbor, &paint);
589 
590  return builder.Build();
591  };
592 
593  ASSERT_TRUE(OpenPlaygroundHere(callback));
594 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [295/454]

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() [296/454]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawWithMatrixFilter   
)

Definition at line 947 of file dl_unittests.cc.

947  {
948  auto boston = CreateTextureForFixture("boston.jpg");
949 
950  auto callback = [&]() {
951  static int selected_matrix_type = 0;
952  const char* matrix_type_names[] = {"Matrix", "Local Matrix"};
953 
954  static float ctm_translation[2] = {200, 200};
955  static float ctm_scale[2] = {0.65, 0.65};
956  static float ctm_skew[2] = {0, 0};
957 
958  static bool enable = true;
959  static float translation[2] = {100, 100};
960  static float scale[2] = {0.8, 0.8};
961  static float skew[2] = {0.2, 0.2};
962 
963  static bool enable_savelayer = true;
964 
965  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
966  {
967  ImGui::Combo("Filter type", &selected_matrix_type, matrix_type_names,
968  sizeof(matrix_type_names) / sizeof(char*));
969 
970  ImGui::TextWrapped("Current Transform");
971  ImGui::SliderFloat2("CTM Translation", ctm_translation, 0, 1000);
972  ImGui::SliderFloat2("CTM Scale", ctm_scale, 0, 3);
973  ImGui::SliderFloat2("CTM Skew", ctm_skew, -3, 3);
974 
975  ImGui::TextWrapped(
976  "MatrixFilter and LocalMatrixFilter modify the CTM in the same way. "
977  "The only difference is that MatrixFilter doesn't affect the effect "
978  "transform, whereas LocalMatrixFilter does.");
979  // Note: See this behavior in:
980  // https://fiddle.skia.org/c/6cbb551ab36d06f163db8693972be954
981  ImGui::Checkbox("Enable", &enable);
982  ImGui::SliderFloat2("Filter Translation", translation, 0, 1000);
983  ImGui::SliderFloat2("Filter Scale", scale, 0, 3);
984  ImGui::SliderFloat2("Filter Skew", skew, -3, 3);
985 
986  ImGui::TextWrapped(
987  "Rendering the filtered image within a layer can expose bounds "
988  "issues. If the rendered image gets cut off when this setting is "
989  "enabled, there's a coverage bug in the filter.");
990  ImGui::Checkbox("Render in layer", &enable_savelayer);
991  }
992  ImGui::End();
993 
994  flutter::DisplayListBuilder builder;
995  flutter::DlPaint paint;
996 
997  if (enable_savelayer) {
998  builder.SaveLayer(nullptr, nullptr);
999  }
1000  {
1001  auto content_scale = GetContentScale();
1002  builder.Scale(content_scale.x, content_scale.y);
1003 
1004  // Set the current transform
1005  auto ctm_matrix =
1006  SkMatrix::MakeAll(ctm_scale[0], ctm_skew[0], ctm_translation[0], //
1007  ctm_skew[1], ctm_scale[1], ctm_translation[1], //
1008  0, 0, 1);
1009  builder.Transform(ctm_matrix);
1010 
1011  // Set the matrix filter
1012  auto filter_matrix =
1013  SkMatrix::MakeAll(scale[0], skew[0], translation[0], //
1014  skew[1], scale[1], translation[1], //
1015  0, 0, 1);
1016 
1017  if (enable) {
1018  switch (selected_matrix_type) {
1019  case 0: {
1020  auto filter = flutter::DlMatrixImageFilter(
1021  filter_matrix, flutter::DlImageSampling::kLinear);
1022  paint.setImageFilter(&filter);
1023  break;
1024  }
1025  case 1: {
1026  auto internal_filter =
1027  flutter::DlBlurImageFilter(10, 10, flutter::DlTileMode::kDecal)
1028  .shared();
1029  auto filter = flutter::DlLocalMatrixImageFilter(filter_matrix,
1030  internal_filter);
1031  paint.setImageFilter(&filter);
1032  break;
1033  }
1034  }
1035  }
1036 
1037  builder.DrawImage(DlImageImpeller::Make(boston), {},
1038  flutter::DlImageSampling::kLinear, &paint);
1039  }
1040  if (enable_savelayer) {
1041  builder.Restore();
1042  }
1043 
1044  return builder.Build();
1045  };
1046 
1047  ASSERT_TRUE(OpenPlaygroundHere(callback));
1048 }

References impeller::DlImageImpeller::Make(), and scale.

◆ TEST_P() [297/454]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawWithMatrixFilterWhenSavingLayer   
)

Definition at line 1050 of file dl_unittests.cc.

1050  {
1051  auto callback = [&]() {
1052  static float translation[2] = {0, 0};
1053  static bool enable_save_layer = true;
1054 
1055  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
1056  ImGui::SliderFloat2("Translation", translation, -130, 130);
1057  ImGui::Checkbox("Enable save layer", &enable_save_layer);
1058  ImGui::End();
1059 
1060  flutter::DisplayListBuilder builder;
1061  builder.Save();
1062  builder.Scale(2.0, 2.0);
1063  flutter::DlPaint paint;
1064  paint.setColor(flutter::DlColor::kYellow());
1065  builder.DrawRect(SkRect::MakeWH(300, 300), paint);
1066  paint.setStrokeWidth(1.0);
1067  paint.setDrawStyle(flutter::DlDrawStyle::kStroke);
1068  paint.setColor(flutter::DlColor::kBlack().withAlpha(0x80));
1069  builder.DrawLine(SkPoint::Make(150, 0), SkPoint::Make(150, 300), paint);
1070  builder.DrawLine(SkPoint::Make(0, 150), SkPoint::Make(300, 150), paint);
1071 
1072  flutter::DlPaint save_paint;
1073  SkRect bounds = SkRect::MakeXYWH(100, 100, 100, 100);
1074  SkMatrix translate_matrix =
1075  SkMatrix::Translate(translation[0], translation[1]);
1076  if (enable_save_layer) {
1077  auto filter = flutter::DlMatrixImageFilter(
1078  translate_matrix, flutter::DlImageSampling::kNearestNeighbor);
1079  save_paint.setImageFilter(filter.shared());
1080  builder.SaveLayer(&bounds, &save_paint);
1081  } else {
1082  builder.Save();
1083  builder.Transform(translate_matrix);
1084  }
1085 
1086  SkMatrix filter_matrix = SkMatrix::I();
1087  filter_matrix.postTranslate(-150, -150);
1088  filter_matrix.postScale(0.2f, 0.2f);
1089  filter_matrix.postTranslate(150, 150);
1090  auto filter = flutter::DlMatrixImageFilter(
1091  filter_matrix, flutter::DlImageSampling::kNearestNeighbor);
1092 
1093  save_paint.setImageFilter(filter.shared());
1094 
1095  builder.SaveLayer(&bounds, &save_paint);
1096  flutter::DlPaint paint2;
1097  paint2.setColor(flutter::DlColor::kBlue());
1098  builder.DrawRect(bounds, paint2);
1099  builder.Restore();
1100  builder.Restore();
1101  return builder.Build();
1102  };
1103 
1104  ASSERT_TRUE(OpenPlaygroundHere(callback));
1105 }

◆ TEST_P() [298/454]

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() [299/454]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawZeroLengthLine   
)

Definition at line 841 of file dl_unittests.cc.

841  {
842  flutter::DisplayListBuilder builder;
843  std::vector<flutter::DlStrokeCap> caps = {
844  flutter::DlStrokeCap::kButt,
845  flutter::DlStrokeCap::kRound,
846  flutter::DlStrokeCap::kSquare,
847  };
848  flutter::DlPaint paint =
849  flutter::DlPaint() //
850  .setColor(flutter::DlColor::kYellow().withAlpha(127)) //
851  .setDrawStyle(flutter::DlDrawStyle::kStroke) //
852  .setStrokeCap(flutter::DlStrokeCap::kButt) //
853  .setStrokeWidth(20);
854  SkPath path = SkPath().addPoly({{150, 50}, {150, 50}}, false);
855  for (auto cap : caps) {
856  paint.setStrokeCap(cap);
857  builder.DrawLine({50, 50}, {50, 50}, paint);
858  builder.DrawPath(path, paint);
859  builder.Translate(0, 150);
860  }
861  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
862 }

◆ TEST_P() [300/454]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawZeroWidthLine   
)

Definition at line 913 of file dl_unittests.cc.

913  {
914  flutter::DisplayListBuilder builder;
915  std::vector<flutter::DlStrokeCap> caps = {
916  flutter::DlStrokeCap::kButt,
917  flutter::DlStrokeCap::kRound,
918  flutter::DlStrokeCap::kSquare,
919  };
920  flutter::DlPaint paint = //
921  flutter::DlPaint() //
922  .setColor(flutter::DlColor::kWhite()) //
923  .setDrawStyle(flutter::DlDrawStyle::kStroke) //
924  .setStrokeWidth(0);
925  flutter::DlPaint outline_paint = //
926  flutter::DlPaint() //
927  .setColor(flutter::DlColor::kYellow()) //
928  .setDrawStyle(flutter::DlDrawStyle::kStroke) //
929  .setStrokeCap(flutter::DlStrokeCap::kSquare) //
930  .setStrokeWidth(1);
931  SkPath path = SkPath().addPoly({{150, 50}, {160, 50}}, false);
932  for (auto cap : caps) {
933  paint.setStrokeCap(cap);
934  builder.DrawLine({50, 50}, {60, 50}, paint);
935  builder.DrawRect({45, 45, 65, 55}, outline_paint);
936  builder.DrawLine({100, 50}, {100, 50}, paint);
937  if (cap != flutter::DlStrokeCap::kButt) {
938  builder.DrawRect({95, 45, 105, 55}, outline_paint);
939  }
940  builder.DrawPath(path, paint);
941  builder.DrawRect(path.getBounds().makeOutset(5, 5), outline_paint);
942  builder.Translate(0, 150);
943  }
944  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
945 }

◆ TEST_P() [301/454]

impeller::testing::TEST_P ( DisplayListTest  ,
ClipDrawRRectWithNonCircularRadii   
)

Definition at line 1330 of file dl_unittests.cc.

1330  {
1331  flutter::DisplayListBuilder builder;
1332 
1333  flutter::DlPaint fill_paint = //
1334  flutter::DlPaint() //
1335  .setColor(flutter::DlColor::kBlue()) //
1336  .setDrawStyle(flutter::DlDrawStyle::kFill) //
1337  .setStrokeWidth(10);
1338  flutter::DlPaint stroke_paint = //
1339  flutter::DlPaint() //
1340  .setColor(flutter::DlColor::kGreen()) //
1341  .setDrawStyle(flutter::DlDrawStyle::kStroke) //
1342  .setStrokeWidth(10);
1343 
1344  builder.DrawRRect(
1345  SkRRect::MakeRectXY(SkRect::MakeXYWH(500, 100, 300, 300), 120, 40),
1346  fill_paint);
1347  builder.DrawRRect(
1348  SkRRect::MakeRectXY(SkRect::MakeXYWH(500, 100, 300, 300), 120, 40),
1349  stroke_paint);
1350 
1351  builder.DrawRRect(
1352  SkRRect::MakeRectXY(SkRect::MakeXYWH(100, 500, 300, 300), 40, 120),
1353  fill_paint);
1354  builder.DrawRRect(
1355  SkRRect::MakeRectXY(SkRect::MakeXYWH(100, 500, 300, 300), 40, 120),
1356  stroke_paint);
1357 
1358  flutter::DlPaint reference_paint = //
1359  flutter::DlPaint() //
1360  .setColor(flutter::DlColor::kMidGrey()) //
1361  .setDrawStyle(flutter::DlDrawStyle::kFill) //
1362  .setStrokeWidth(10);
1363 
1364  builder.DrawRRect(
1365  SkRRect::MakeRectXY(SkRect::MakeXYWH(500, 500, 300, 300), 40, 40),
1366  reference_paint);
1367  builder.DrawRRect(
1368  SkRRect::MakeRectXY(SkRect::MakeXYWH(100, 100, 300, 300), 120, 120),
1369  reference_paint);
1370 
1371  flutter::DlPaint clip_fill_paint = //
1372  flutter::DlPaint() //
1373  .setColor(flutter::DlColor::kCyan()) //
1374  .setDrawStyle(flutter::DlDrawStyle::kFill) //
1375  .setStrokeWidth(10);
1376 
1377  builder.Save();
1378  builder.ClipRRect(
1379  SkRRect::MakeRectXY(SkRect::MakeXYWH(900, 100, 300, 300), 120, 40));
1380  builder.DrawPaint(clip_fill_paint);
1381  builder.Restore();
1382 
1383  builder.Save();
1384  builder.ClipRRect(
1385  SkRRect::MakeRectXY(SkRect::MakeXYWH(100, 900, 300, 300), 40, 120));
1386  builder.DrawPaint(clip_fill_paint);
1387  builder.Restore();
1388 
1389  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1390 }

◆ TEST_P() [302/454]

impeller::testing::TEST_P ( DisplayListTest  ,
DrawMaskBlursThatMightUseSaveLayers   
)

Definition at line 1506 of file dl_unittests.cc.

1506  {
1507  flutter::DisplayListBuilder builder;
1508  builder.DrawColor(flutter::DlColor::kWhite(), flutter::DlBlendMode::kSrc);
1509  Vector2 scale = GetContentScale();
1510  builder.Scale(scale.x, scale.y);
1511 
1512  builder.Save();
1513  // We need a small transform op to avoid a deferred save
1514  builder.Translate(1.0f, 1.0f);
1515  auto solid_filter =
1516  flutter::DlBlurMaskFilter::Make(flutter::DlBlurStyle::kSolid, 5.0f);
1517  flutter::DlPaint solid_alpha_paint =
1518  flutter::DlPaint() //
1519  .setMaskFilter(solid_filter) //
1520  .setColor(flutter::DlColor::kBlue()) //
1521  .setAlpha(0x7f);
1522  for (int x = 1; x <= 4; x++) {
1523  for (int y = 1; y <= 4; y++) {
1524  builder.DrawRect(SkRect::MakeXYWH(x * 100, y * 100, 80, 80),
1525  solid_alpha_paint);
1526  }
1527  }
1528  builder.Restore();
1529 
1530  builder.Save();
1531  builder.Translate(500.0f, 0.0f);
1532  auto normal_filter =
1533  flutter::DlBlurMaskFilter::Make(flutter::DlBlurStyle::kNormal, 5.0f);
1534  auto rotate_if = flutter::DlMatrixImageFilter::Make(
1535  SkMatrix::RotateDeg(10), flutter::DlImageSampling::kLinear);
1536  flutter::DlPaint normal_if_paint =
1537  flutter::DlPaint() //
1538  .setMaskFilter(solid_filter) //
1539  .setImageFilter(rotate_if) //
1540  .setColor(flutter::DlColor::kGreen()) //
1541  .setAlpha(0x7f);
1542  for (int x = 1; x <= 4; x++) {
1543  for (int y = 1; y <= 4; y++) {
1544  builder.DrawRect(SkRect::MakeXYWH(x * 100, y * 100, 80, 80),
1545  normal_if_paint);
1546  }
1547  }
1548  builder.Restore();
1549 
1550  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1551 }

References scale.

◆ TEST_P() [303/454]

impeller::testing::TEST_P ( DisplayListTest  ,
DrawPaintIgnoresMaskFilter   
)

Definition at line 1483 of file dl_unittests.cc.

1483  {
1484  flutter::DisplayListBuilder builder;
1485  builder.DrawPaint(flutter::DlPaint().setColor(flutter::DlColor::kWhite()));
1486 
1487  auto filter = flutter::DlBlurMaskFilter(flutter::DlBlurStyle::kNormal, 10.0f);
1488  builder.DrawCircle({300, 300}, 200,
1489  flutter::DlPaint().setMaskFilter(&filter));
1490 
1491  std::vector<flutter::DlColor> colors = {flutter::DlColor::kGreen(),
1492  flutter::DlColor::kGreen()};
1493  const float stops[2] = {0.0, 1.0};
1494  auto linear = flutter::DlColorSource::MakeLinear(
1495  {100.0, 100.0}, {300.0, 300.0}, 2, colors.data(), stops,
1496  flutter::DlTileMode::kRepeat);
1497  flutter::DlPaint blend_paint =
1498  flutter::DlPaint() //
1499  .setColorSource(linear) //
1500  .setBlendMode(flutter::DlBlendMode::kScreen);
1501  builder.DrawPaint(blend_paint);
1502 
1503  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1504 }

◆ TEST_P() [304/454]

impeller::testing::TEST_P ( DisplayListTest  ,
DrawShapes   
)

Definition at line 1292 of file dl_unittests.cc.

1292  {
1293  flutter::DisplayListBuilder builder;
1294  std::vector<flutter::DlStrokeJoin> joins = {
1295  flutter::DlStrokeJoin::kBevel,
1296  flutter::DlStrokeJoin::kRound,
1297  flutter::DlStrokeJoin::kMiter,
1298  };
1299  flutter::DlPaint paint = //
1300  flutter::DlPaint() //
1301  .setColor(flutter::DlColor::kWhite()) //
1302  .setDrawStyle(flutter::DlDrawStyle::kFill) //
1303  .setStrokeWidth(10);
1304  flutter::DlPaint stroke_paint = //
1305  flutter::DlPaint() //
1306  .setColor(flutter::DlColor::kWhite()) //
1307  .setDrawStyle(flutter::DlDrawStyle::kStroke) //
1308  .setStrokeWidth(10);
1309  SkPath path = SkPath().addPoly({{150, 50}, {160, 50}}, false);
1310 
1311  builder.Translate(300, 50);
1312  builder.Scale(0.8, 0.8);
1313  for (auto join : joins) {
1314  paint.setStrokeJoin(join);
1315  stroke_paint.setStrokeJoin(join);
1316  builder.DrawRect(SkRect::MakeXYWH(0, 0, 100, 100), paint);
1317  builder.DrawRect(SkRect::MakeXYWH(0, 150, 100, 100), stroke_paint);
1318  builder.DrawRRect(
1319  SkRRect::MakeRectXY(SkRect::MakeXYWH(150, 0, 100, 100), 30, 30), paint);
1320  builder.DrawRRect(
1321  SkRRect::MakeRectXY(SkRect::MakeXYWH(150, 150, 100, 100), 30, 30),
1322  stroke_paint);
1323  builder.DrawCircle({350, 50}, 50, paint);
1324  builder.DrawCircle({350, 200}, 50, stroke_paint);
1325  builder.Translate(0, 300);
1326  }
1327  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1328 }

◆ TEST_P() [305/454]

impeller::testing::TEST_P ( DisplayListTest  ,
DrawVerticesBlendModes   
)

Definition at line 1392 of file dl_unittests.cc.

1392  {
1393  std::vector<const char*> blend_mode_names;
1394  std::vector<flutter::DlBlendMode> blend_mode_values;
1395  {
1396  const std::vector<std::tuple<const char*, flutter::DlBlendMode>> blends = {
1397  // Pipeline blends (Porter-Duff alpha compositing)
1398  {"Clear", flutter::DlBlendMode::kClear},
1399  {"Source", flutter::DlBlendMode::kSrc},
1400  {"Destination", flutter::DlBlendMode::kDst},
1401  {"SourceOver", flutter::DlBlendMode::kSrcOver},
1402  {"DestinationOver", flutter::DlBlendMode::kDstOver},
1403  {"SourceIn", flutter::DlBlendMode::kSrcIn},
1404  {"DestinationIn", flutter::DlBlendMode::kDstIn},
1405  {"SourceOut", flutter::DlBlendMode::kSrcOut},
1406  {"DestinationOut", flutter::DlBlendMode::kDstOut},
1407  {"SourceATop", flutter::DlBlendMode::kSrcATop},
1408  {"DestinationATop", flutter::DlBlendMode::kDstATop},
1409  {"Xor", flutter::DlBlendMode::kXor},
1410  {"Plus", flutter::DlBlendMode::kPlus},
1411  {"Modulate", flutter::DlBlendMode::kModulate},
1412  // Advanced blends (color component blends)
1413  {"Screen", flutter::DlBlendMode::kScreen},
1414  {"Overlay", flutter::DlBlendMode::kOverlay},
1415  {"Darken", flutter::DlBlendMode::kDarken},
1416  {"Lighten", flutter::DlBlendMode::kLighten},
1417  {"ColorDodge", flutter::DlBlendMode::kColorDodge},
1418  {"ColorBurn", flutter::DlBlendMode::kColorBurn},
1419  {"HardLight", flutter::DlBlendMode::kHardLight},
1420  {"SoftLight", flutter::DlBlendMode::kSoftLight},
1421  {"Difference", flutter::DlBlendMode::kDifference},
1422  {"Exclusion", flutter::DlBlendMode::kExclusion},
1423  {"Multiply", flutter::DlBlendMode::kMultiply},
1424  {"Hue", flutter::DlBlendMode::kHue},
1425  {"Saturation", flutter::DlBlendMode::kSaturation},
1426  {"Color", flutter::DlBlendMode::kColor},
1427  {"Luminosity", flutter::DlBlendMode::kLuminosity},
1428  };
1429  assert(blends.size() ==
1430  static_cast<size_t>(flutter::DlBlendMode::kLastMode) + 1);
1431  for (const auto& [name, mode] : blends) {
1432  blend_mode_names.push_back(name);
1433  blend_mode_values.push_back(mode);
1434  }
1435  }
1436 
1437  auto callback = [&]() {
1438  static int current_blend_index = 3;
1439  static float dst_alpha = 1;
1440  static float src_alpha = 1;
1441  static float color0[4] = {1.0f, 0.0f, 0.0f, 1.0f};
1442  static float color1[4] = {0.0f, 1.0f, 0.0f, 1.0f};
1443  static float color2[4] = {0.0f, 0.0f, 1.0f, 1.0f};
1444  static float src_color[4] = {1.0f, 1.0f, 1.0f, 1.0f};
1445 
1446  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
1447  {
1448  ImGui::ListBox("Blending mode", &current_blend_index,
1449  blend_mode_names.data(), blend_mode_names.size());
1450  ImGui::SliderFloat("Source alpha", &src_alpha, 0, 1);
1451  ImGui::ColorEdit4("Color A", color0);
1452  ImGui::ColorEdit4("Color B", color1);
1453  ImGui::ColorEdit4("Color C", color2);
1454  ImGui::ColorEdit4("Source Color", src_color);
1455  ImGui::SliderFloat("Destination alpha", &dst_alpha, 0, 1);
1456  }
1457  ImGui::End();
1458 
1459  std::vector<SkPoint> positions = {SkPoint::Make(100, 300),
1460  SkPoint::Make(200, 100),
1461  SkPoint::Make(300, 300)};
1462  std::vector<flutter::DlColor> colors = {
1463  toColor(color0).modulateOpacity(dst_alpha),
1464  toColor(color1).modulateOpacity(dst_alpha),
1465  toColor(color2).modulateOpacity(dst_alpha)};
1466 
1467  auto vertices = flutter::DlVertices::Make(
1468  flutter::DlVertexMode::kTriangles, 3, positions.data(),
1469  /*texture_coordinates=*/nullptr, colors.data());
1470 
1471  flutter::DisplayListBuilder builder;
1472  flutter::DlPaint paint;
1473 
1474  paint.setColor(toColor(src_color).modulateOpacity(src_alpha));
1475  builder.DrawVertices(vertices, blend_mode_values[current_blend_index],
1476  paint);
1477  return builder.Build();
1478  };
1479 
1480  ASSERT_TRUE(OpenPlaygroundHere(callback));
1481 }

References toColor().

◆ TEST_P() [306/454]

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() [307/454]

impeller::testing::TEST_P ( DisplayListTest  ,
MaskBlursApplyCorrectlyToColorSources   
)

Definition at line 1255 of file dl_unittests.cc.

1255  {
1256  auto blur_filter = std::make_shared<flutter::DlBlurMaskFilter>(
1257  flutter::DlBlurStyle::kNormal, 10);
1258 
1259  flutter::DisplayListBuilder builder;
1260 
1261  std::array<flutter::DlColor, 2> colors = {flutter::DlColor::kBlue(),
1262  flutter::DlColor::kGreen()};
1263  std::array<float, 2> stops = {0, 1};
1264  std::array<std::shared_ptr<flutter::DlColorSource>, 2> color_sources = {
1265  std::make_shared<flutter::DlColorColorSource>(flutter::DlColor::kWhite()),
1266  flutter::DlColorSource::MakeLinear(
1267  SkPoint::Make(0, 0), SkPoint::Make(100, 50), 2, colors.data(),
1268  stops.data(), flutter::DlTileMode::kClamp)};
1269 
1270  int offset = 100;
1271  for (const auto& color_source : color_sources) {
1272  flutter::DlPaint paint;
1273  paint.setColorSource(color_source);
1274  paint.setMaskFilter(blur_filter);
1275 
1276  paint.setDrawStyle(flutter::DlDrawStyle::kFill);
1277  builder.DrawRRect(
1278  SkRRect::MakeRectXY(SkRect::MakeXYWH(100, offset, 100, 50), 30, 30),
1279  paint);
1280  paint.setDrawStyle(flutter::DlDrawStyle::kStroke);
1281  paint.setStrokeWidth(10);
1282  builder.DrawRRect(
1283  SkRRect::MakeRectXY(SkRect::MakeXYWH(300, offset, 100, 50), 30, 30),
1284  paint);
1285 
1286  offset += 100;
1287  }
1288 
1289  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1290 }

References offset.

◆ TEST_P() [308/454]

impeller::testing::TEST_P ( DisplayListTest  ,
NinePatchImagePrecision   
)

Definition at line 793 of file dl_unittests.cc.

793  {
794  // Draw a nine patch image with colored corners and verify that the corner
795  // color does not leak outside the intended region.
796  auto texture = CreateTextureForFixture("nine_patch_corners.png");
797  flutter::DisplayListBuilder builder;
798  builder.DrawImageNine(DlImageImpeller::Make(texture),
799  SkIRect::MakeXYWH(10, 10, 1, 1),
800  SkRect::MakeXYWH(0, 0, 200, 100),
801  flutter::DlFilterMode::kNearest, nullptr);
802  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
803 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [309/454]

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() [310/454]

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() [311/454]

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() [312/454]

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() [313/454]

impeller::testing::TEST_P ( EntityPassTargetTest  ,
SwapWithMSAAImplicitResolve   
)

Definition at line 53 of file entity_pass_target_unittests.cc.

53  {
54  auto content_context = GetContentContext();
55  auto buffer = content_context->GetContext()->CreateCommandBuffer();
56  auto context = content_context->GetContext();
57  auto& allocator = *context->GetResourceAllocator();
58 
59  // Emulate implicit MSAA resolve by making color resolve and msaa texture the
60  // same.
61  RenderTarget render_target;
62  {
63  PixelFormat pixel_format =
64  context->GetCapabilities()->GetDefaultColorFormat();
65 
66  // Create MSAA color texture.
67 
68  TextureDescriptor color0_tex_desc;
69  color0_tex_desc.storage_mode = StorageMode::kDevicePrivate;
70  color0_tex_desc.type = TextureType::kTexture2DMultisample;
71  color0_tex_desc.sample_count = SampleCount::kCount4;
72  color0_tex_desc.format = pixel_format;
73  color0_tex_desc.size = ISize{100, 100};
74  color0_tex_desc.usage = TextureUsage::kRenderTarget;
75 
76  auto color0_msaa_tex = allocator.CreateTexture(color0_tex_desc);
77 
78  // Color attachment.
79 
80  ColorAttachment color0;
81  color0.load_action = LoadAction::kDontCare;
82  color0.store_action = StoreAction::kStoreAndMultisampleResolve;
83  color0.texture = color0_msaa_tex;
84  color0.resolve_texture = color0_msaa_tex;
85 
86  render_target.SetColorAttachment(color0, 0u);
87  render_target.SetStencilAttachment(std::nullopt);
88  }
89 
90  auto entity_pass_target = EntityPassTarget(render_target, false, true);
91 
92  auto color0 = entity_pass_target.GetRenderTarget()
93  .GetColorAttachments()
94  .find(0u)
95  ->second;
96  auto msaa_tex = color0.texture;
97  auto resolve_tex = color0.resolve_texture;
98 
99  ASSERT_EQ(msaa_tex, resolve_tex);
100 
101  entity_pass_target.Flip(
102  *content_context->GetContext()->GetResourceAllocator());
103 
104  color0 = entity_pass_target.GetRenderTarget()
105  .GetColorAttachments()
106  .find(0u)
107  ->second;
108 
109  ASSERT_NE(msaa_tex, color0.texture);
110  ASSERT_NE(resolve_tex, color0.resolve_texture);
111  ASSERT_EQ(color0.texture, color0.resolve_texture);
112 }

References impeller::TextureDescriptor::format, impeller::kCount4, impeller::kDevicePrivate, impeller::kDontCare, impeller::kRenderTarget, impeller::kStoreAndMultisampleResolve, impeller::kTexture2DMultisample, impeller::Attachment::load_action, impeller::Attachment::resolve_texture, impeller::TextureDescriptor::sample_count, impeller::RenderTarget::SetColorAttachment(), impeller::RenderTarget::SetStencilAttachment(), impeller::TextureDescriptor::size, impeller::TextureDescriptor::storage_mode, impeller::Attachment::store_action, impeller::Attachment::texture, impeller::TextureDescriptor::type, and impeller::TextureDescriptor::usage.

◆ TEST_P() [314/454]

impeller::testing::TEST_P ( EntityPassTargetTest  ,
SwapWithMSAATexture   
)

Definition at line 19 of file entity_pass_target_unittests.cc.

19  {
20  if (GetContentContext()
21  ->GetDeviceCapabilities()
22  .SupportsImplicitResolvingMSAA()) {
23  GTEST_SKIP() << "Implicit MSAA is used on this device.";
24  }
25  auto content_context = GetContentContext();
26  auto buffer = content_context->GetContext()->CreateCommandBuffer();
27  auto render_target =
28  GetContentContext()->GetRenderTargetCache()->CreateOffscreenMSAA(
29  *content_context->GetContext(), {100, 100},
30  /*mip_count=*/1);
31 
32  auto entity_pass_target = EntityPassTarget(render_target, false, false);
33 
34  auto color0 = entity_pass_target.GetRenderTarget()
35  .GetColorAttachments()
36  .find(0u)
37  ->second;
38  auto msaa_tex = color0.texture;
39  auto resolve_tex = color0.resolve_texture;
40 
41  entity_pass_target.Flip(
42  *content_context->GetContext()->GetResourceAllocator());
43 
44  color0 = entity_pass_target.GetRenderTarget()
45  .GetColorAttachments()
46  .find(0u)
47  ->second;
48 
49  ASSERT_EQ(msaa_tex, color0.texture);
50  ASSERT_NE(resolve_tex, color0.resolve_texture);
51 }

◆ TEST_P() [315/454]

impeller::testing::TEST_P ( EntityTest  ,
BezierCircleScaled   
)

Definition at line 830 of file entity_unittests.cc.

830  {
831  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
832  static float scale = 20;
833 
834  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
835  ImGui::SliderFloat("Scale", &scale, 1, 100);
836  ImGui::End();
837 
838  Entity entity;
839  entity.SetTransform(Matrix::MakeScale(GetContentScale()));
840  auto path = PathBuilder{}
841  .MoveTo({97.325, 34.818})
842  .CubicCurveTo({98.50862885295136, 34.81812293973836},
843  {99.46822048142015, 33.85863261475589},
844  {99.46822048142015, 32.67499810206613})
845  .CubicCurveTo({99.46822048142015, 31.491363589376355},
846  {98.50862885295136, 30.53187326439389},
847  {97.32499434685802, 30.531998226542708})
848  .CubicCurveTo({96.14153655073771, 30.532123170035373},
849  {95.18222070648729, 31.491540299350355},
850  {95.18222070648729, 32.67499810206613})
851  .CubicCurveTo({95.18222070648729, 33.85845590478189},
852  {96.14153655073771, 34.81787303409686},
853  {97.32499434685802, 34.81799797758954})
854  .Close()
855  .TakePath();
856  entity.SetTransform(
857  Matrix::MakeScale({scale, scale, 1.0}).Translate({-90, -20, 0}));
858 
859  static std::unique_ptr<Geometry> geom = Geometry::MakeFillPath(path);
860 
861  auto contents = std::make_shared<SolidColorContents>();
862  contents->SetColor(Color::Red());
863  contents->SetGeometry(geom.get());
864 
865  entity.SetContents(contents);
866  return entity.Render(context, pass);
867  };
868  ASSERT_TRUE(OpenPlaygroundHere(callback));
869 }

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() [316/454]

impeller::testing::TEST_P ( EntityTest  ,
BlendingModeOptions   
)

Definition at line 699 of file entity_unittests.cc.

699  {
700  std::vector<const char*> blend_mode_names;
701  std::vector<BlendMode> blend_mode_values;
702  {
703  // Force an exhausiveness check with a switch. When adding blend modes,
704  // update this switch with a new name/value to make it selectable in the
705  // test GUI.
706 
707  const BlendMode b{};
708  static_assert(b == BlendMode::kClear); // Ensure the first item in
709  // the switch is the first
710  // item in the enum.
711  static_assert(Entity::kLastPipelineBlendMode == BlendMode::kModulate);
712  switch (b) {
713  case BlendMode::kClear:
714  blend_mode_names.push_back("Clear");
715  blend_mode_values.push_back(BlendMode::kClear);
716  case BlendMode::kSource:
717  blend_mode_names.push_back("Source");
718  blend_mode_values.push_back(BlendMode::kSource);
719  case BlendMode::kDestination:
720  blend_mode_names.push_back("Destination");
721  blend_mode_values.push_back(BlendMode::kDestination);
722  case BlendMode::kSourceOver:
723  blend_mode_names.push_back("SourceOver");
724  blend_mode_values.push_back(BlendMode::kSourceOver);
725  case BlendMode::kDestinationOver:
726  blend_mode_names.push_back("DestinationOver");
727  blend_mode_values.push_back(BlendMode::kDestinationOver);
728  case BlendMode::kSourceIn:
729  blend_mode_names.push_back("SourceIn");
730  blend_mode_values.push_back(BlendMode::kSourceIn);
731  case BlendMode::kDestinationIn:
732  blend_mode_names.push_back("DestinationIn");
733  blend_mode_values.push_back(BlendMode::kDestinationIn);
734  case BlendMode::kSourceOut:
735  blend_mode_names.push_back("SourceOut");
736  blend_mode_values.push_back(BlendMode::kSourceOut);
737  case BlendMode::kDestinationOut:
738  blend_mode_names.push_back("DestinationOut");
739  blend_mode_values.push_back(BlendMode::kDestinationOut);
740  case BlendMode::kSourceATop:
741  blend_mode_names.push_back("SourceATop");
742  blend_mode_values.push_back(BlendMode::kSourceATop);
743  case BlendMode::kDestinationATop:
744  blend_mode_names.push_back("DestinationATop");
745  blend_mode_values.push_back(BlendMode::kDestinationATop);
746  case BlendMode::kXor:
747  blend_mode_names.push_back("Xor");
748  blend_mode_values.push_back(BlendMode::kXor);
749  case BlendMode::kPlus:
750  blend_mode_names.push_back("Plus");
751  blend_mode_values.push_back(BlendMode::kPlus);
752  case BlendMode::kModulate:
753  blend_mode_names.push_back("Modulate");
754  blend_mode_values.push_back(BlendMode::kModulate);
755  };
756  }
757 
758  auto callback = [&](ContentContext& context, RenderPass& pass) {
759  auto world_matrix = Matrix::MakeScale(GetContentScale());
760  auto draw_rect = [&context, &pass, &world_matrix](
761  Rect rect, Color color, BlendMode blend_mode) -> bool {
762  using VS = SolidFillPipeline::VertexShader;
763  using FS = SolidFillPipeline::FragmentShader;
764 
765  VertexBufferBuilder<VS::PerVertexData> vtx_builder;
766  {
767  auto r = rect.GetLTRB();
768  vtx_builder.AddVertices({
769  {Point(r[0], r[1])},
770  {Point(r[2], r[1])},
771  {Point(r[2], r[3])},
772  {Point(r[0], r[1])},
773  {Point(r[2], r[3])},
774  {Point(r[0], r[3])},
775  });
776  }
777 
778  pass.SetCommandLabel("Blended Rectangle");
779  auto options = OptionsFromPass(pass);
780  options.blend_mode = blend_mode;
781  options.primitive_type = PrimitiveType::kTriangle;
782  pass.SetPipeline(context.GetSolidFillPipeline(options));
783  pass.SetVertexBuffer(
784  vtx_builder.CreateVertexBuffer(context.GetTransientsBuffer()));
785 
786  VS::FrameInfo frame_info;
787  frame_info.mvp = pass.GetOrthographicTransform() * world_matrix;
788  VS::BindFrameInfo(
789  pass, context.GetTransientsBuffer().EmplaceUniform(frame_info));
790  FS::FragInfo frag_info;
791  frag_info.color = color.Premultiply();
792  FS::BindFragInfo(
793  pass, context.GetTransientsBuffer().EmplaceUniform(frame_info));
794  return pass.Draw().ok();
795  };
796 
797  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
798  static Color color1(1, 0, 0, 0.5), color2(0, 1, 0, 0.5);
799  ImGui::ColorEdit4("Color 1", reinterpret_cast<float*>(&color1));
800  ImGui::ColorEdit4("Color 2", reinterpret_cast<float*>(&color2));
801  static int current_blend_index = 3;
802  ImGui::ListBox("Blending mode", &current_blend_index,
803  blend_mode_names.data(), blend_mode_names.size());
804  ImGui::End();
805 
806  BlendMode selected_mode = blend_mode_values[current_blend_index];
807 
808  Point a, b, c, d;
809  static PlaygroundPoint point_a(Point(400, 100), 20, Color::White());
810  static PlaygroundPoint point_b(Point(200, 300), 20, Color::White());
811  std::tie(a, b) = DrawPlaygroundLine(point_a, point_b);
812  static PlaygroundPoint point_c(Point(470, 190), 20, Color::White());
813  static PlaygroundPoint point_d(Point(270, 390), 20, Color::White());
814  std::tie(c, d) = DrawPlaygroundLine(point_c, point_d);
815 
816  bool result = true;
817  result = result &&
818  draw_rect(Rect::MakeXYWH(0, 0, pass.GetRenderTargetSize().width,
819  pass.GetRenderTargetSize().height),
820  Color(), BlendMode::kClear);
821  result = result && draw_rect(Rect::MakeLTRB(a.x, a.y, b.x, b.y), color1,
822  BlendMode::kSourceOver);
823  result = result && draw_rect(Rect::MakeLTRB(c.x, c.y, d.x, d.y), color2,
824  selected_mode);
825  return result;
826  };
827  ASSERT_TRUE(OpenPlaygroundHere(callback));
828 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), impeller::saturated::b, color, impeller::VertexBufferBuilder< VertexType_, IndexType_ >::CreateVertexBuffer(), impeller::DrawPlaygroundLine(), impeller::HostBuffer::EmplaceUniform(), impeller::ContentContext::GetSolidFillPipeline(), impeller::ContentContext::GetTransientsBuffer(), impeller::kClear, impeller::kDestination, impeller::kDestinationATop, impeller::kDestinationIn, impeller::kDestinationOut, impeller::kDestinationOver, impeller::Entity::kLastPipelineBlendMode, impeller::kModulate, impeller::kPlus, impeller::kSource, impeller::kSourceATop, impeller::kSourceIn, impeller::kSourceOut, impeller::kSourceOver, impeller::kTriangle, impeller::kXor, impeller::TRect< Scalar >::MakeLTRB(), impeller::Matrix::MakeScale(), impeller::TRect< Scalar >::MakeXYWH(), impeller::OptionsFromPass(), impeller::Color::White(), impeller::TPoint< T >::x, and impeller::TPoint< T >::y.

◆ TEST_P() [317/454]

impeller::testing::TEST_P ( EntityTest  ,
BorderMaskBlurCoverageIsCorrect   
)

Definition at line 1257 of file entity_unittests.cc.

1257  {
1258  auto fill = std::make_shared<SolidColorContents>();
1259  auto geom = Geometry::MakeFillPath(
1260  PathBuilder{}.AddRect(Rect::MakeXYWH(0, 0, 300, 400)).TakePath());
1261  fill->SetGeometry(geom.get());
1262  fill->SetColor(Color::CornflowerBlue());
1263  auto border_mask_blur = FilterContents::MakeBorderMaskBlur(
1264  FilterInput::Make(fill), Radius{3}, Radius{4});
1265 
1266  {
1267  Entity e;
1268  e.SetTransform(Matrix());
1269  auto actual = border_mask_blur->GetCoverage(e);
1270  auto expected = Rect::MakeXYWH(-3, -4, 306, 408);
1271  ASSERT_TRUE(actual.has_value());
1272  ASSERT_RECT_NEAR(actual.value(), expected);
1273  }
1274 
1275  {
1276  Entity e;
1277  e.SetTransform(Matrix::MakeRotationZ(Radians{kPi / 4}));
1278  auto actual = border_mask_blur->GetCoverage(e);
1279  auto expected = Rect::MakeXYWH(-287.792, -4.94975, 504.874, 504.874);
1280  ASSERT_TRUE(actual.has_value());
1281  ASSERT_RECT_NEAR(actual.value(), expected);
1282  }
1283 }

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() [318/454]

impeller::testing::TEST_P ( EntityTest  ,
CanComputeGeometryForEmptyPathsWithoutCrashing   
)

Definition at line 2325 of file entity_unittests.cc.

2325  {
2326  PathBuilder builder = {};
2327  builder.AddRect(Rect::MakeLTRB(0, 0, 0, 0));
2328  Path path = builder.TakePath();
2329 
2330  EXPECT_TRUE(path.GetBoundingBox()->IsEmpty());
2331 
2332  auto geom = Geometry::MakeFillPath(path);
2333 
2334  Entity entity;
2335  RenderTarget target =
2336  GetContentContext()->GetRenderTargetCache()->CreateOffscreen(
2337  *GetContext(), {1, 1}, 1u);
2338  testing::MockRenderPass render_pass(GetContext(), target);
2339  auto position_result =
2340  geom->GetPositionBuffer(*GetContentContext(), entity, render_pass);
2341 
2342  EXPECT_EQ(position_result.vertex_buffer.vertex_count, 0u);
2343 
2344  EXPECT_EQ(geom->GetResultMode(), GeometryResult::Mode::kNormal);
2345 }

References impeller::PathBuilder::AddRect(), impeller::Path::GetBoundingBox(), impeller::GeometryResult::kNormal, impeller::Geometry::MakeFillPath(), impeller::TRect< Scalar >::MakeLTRB(), and impeller::PathBuilder::TakePath().

◆ TEST_P() [319/454]

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() [320/454]

impeller::testing::TEST_P ( EntityTest  ,
CanDrawCorrectlyWithRotatedTransform   
)

Definition at line 367 of file entity_unittests.cc.

367  {
368  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
369  const char* input_axis[] = {"X", "Y", "Z"};
370  static int rotation_axis_index = 0;
371  static float rotation = 0;
372  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
373  ImGui::SliderFloat("Rotation", &rotation, -kPi, kPi);
374  ImGui::Combo("Rotation Axis", &rotation_axis_index, input_axis,
375  sizeof(input_axis) / sizeof(char*));
376  Matrix rotation_matrix;
377  switch (rotation_axis_index) {
378  case 0:
379  rotation_matrix = Matrix::MakeRotationX(Radians(rotation));
380  break;
381  case 1:
382  rotation_matrix = Matrix::MakeRotationY(Radians(rotation));
383  break;
384  case 2:
385  rotation_matrix = Matrix::MakeRotationZ(Radians(rotation));
386  break;
387  default:
388  rotation_matrix = Matrix{};
389  break;
390  }
391 
392  if (ImGui::Button("Reset")) {
393  rotation = 0;
394  }
395  ImGui::End();
396  Matrix current_transform =
397  Matrix::MakeScale(GetContentScale())
398  .MakeTranslation(
399  Vector3(Point(pass.GetRenderTargetSize().width / 2.0,
400  pass.GetRenderTargetSize().height / 2.0)));
401  Matrix result_transform = current_transform * rotation_matrix;
402  Path path =
403  PathBuilder{}.AddRect(Rect::MakeXYWH(-300, -400, 600, 800)).TakePath();
404 
405  Entity entity;
406  entity.SetTransform(result_transform);
407 
408  static std::unique_ptr<Geometry> geom = Geometry::MakeFillPath(path);
409 
410  auto contents = std::make_shared<SolidColorContents>();
411  contents->SetColor(Color::Red());
412  contents->SetGeometry(geom.get());
413 
414  entity.SetContents(contents);
415  return entity.Render(context, pass);
416  };
417  ASSERT_TRUE(OpenPlaygroundHere(callback));
418 }

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() [321/454]

impeller::testing::TEST_P ( EntityTest  ,
CanRenderEmptyPathsWithoutCrashing   
)

Definition at line 2347 of file entity_unittests.cc.

2347  {
2348  PathBuilder builder = {};
2349  builder.AddRect(Rect::MakeLTRB(0, 0, 0, 0));
2350  Path path = builder.TakePath();
2351 
2352  EXPECT_TRUE(path.GetBoundingBox()->IsEmpty());
2353 
2354  auto contents = std::make_shared<SolidColorContents>();
2355  static std::unique_ptr<Geometry> geom = Geometry::MakeFillPath(path);
2356  contents->SetGeometry(geom.get());
2357  contents->SetColor(Color::Red());
2358 
2359  Entity entity;
2360  entity.SetTransform(Matrix::MakeScale(GetContentScale()));
2361  entity.SetContents(contents);
2362 
2363  ASSERT_TRUE(OpenPlaygroundHere(std::move(entity)));
2364 }

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() [322/454]

impeller::testing::TEST_P ( EntityTest  ,
ClipContentsGetClipCoverageIsCorrect   
)

Definition at line 1331 of file entity_unittests.cc.

1331  {
1332  // Intersection: No stencil coverage, no geometry.
1333  {
1334  auto clip = std::make_shared<ClipContents>();
1335  clip->SetClipOperation(Entity::ClipOperation::kIntersect);
1336  auto result = clip->GetClipCoverage(Entity{}, Rect{});
1337 
1338  ASSERT_FALSE(result.coverage.has_value());
1339  }
1340 
1341  // Intersection: No stencil coverage, with geometry.
1342  {
1343  auto clip = std::make_shared<ClipContents>();
1344  auto geom = Geometry::MakeFillPath(
1345  PathBuilder{}.AddRect(Rect::MakeLTRB(0, 0, 100, 100)).TakePath());
1346  clip->SetClipOperation(Entity::ClipOperation::kIntersect);
1347  clip->SetGeometry(geom.get());
1348  auto result = clip->GetClipCoverage(Entity{}, Rect{});
1349 
1350  ASSERT_FALSE(result.coverage.has_value());
1351  }
1352 
1353  // Intersection: With stencil coverage, no geometry.
1354  {
1355  auto clip = std::make_shared<ClipContents>();
1356  clip->SetClipOperation(Entity::ClipOperation::kIntersect);
1357  auto result =
1358  clip->GetClipCoverage(Entity{}, Rect::MakeLTRB(0, 0, 100, 100));
1359 
1360  ASSERT_FALSE(result.coverage.has_value());
1361  }
1362 
1363  // Intersection: With stencil coverage, with geometry.
1364  {
1365  auto clip = std::make_shared<ClipContents>();
1366  auto geom = Geometry::MakeFillPath(
1367  PathBuilder{}.AddRect(Rect::MakeLTRB(0, 0, 50, 50)).TakePath());
1368  clip->SetClipOperation(Entity::ClipOperation::kIntersect);
1369  clip->SetGeometry(geom.get());
1370  auto result =
1371  clip->GetClipCoverage(Entity{}, Rect::MakeLTRB(0, 0, 100, 100));
1372 
1373  ASSERT_TRUE(result.coverage.has_value());
1374  ASSERT_RECT_NEAR(result.coverage.value(), Rect::MakeLTRB(0, 0, 50, 50));
1375  ASSERT_EQ(result.type, Contents::ClipCoverage::Type::kAppend);
1376  }
1377 
1378  // Difference: With stencil coverage, with geometry.
1379  {
1380  auto clip = std::make_shared<ClipContents>();
1381  auto geom = Geometry::MakeFillPath(
1382  PathBuilder{}.AddRect(Rect::MakeLTRB(0, 0, 50, 50)).TakePath());
1383  clip->SetClipOperation(Entity::ClipOperation::kDifference);
1384  clip->SetGeometry(geom.get());
1385  auto result =
1386  clip->GetClipCoverage(Entity{}, Rect::MakeLTRB(0, 0, 100, 100));
1387 
1388  ASSERT_TRUE(result.coverage.has_value());
1389  ASSERT_RECT_NEAR(result.coverage.value(), Rect::MakeLTRB(0, 0, 100, 100));
1390  ASSERT_EQ(result.type, Contents::ClipCoverage::Type::kAppend);
1391  }
1392 }

References impeller::PathBuilder::AddRect(), ASSERT_RECT_NEAR, impeller::Contents::ClipCoverage::kAppend, impeller::Entity::kDifference, impeller::Entity::kIntersect, impeller::Geometry::MakeFillPath(), and impeller::TRect< Scalar >::MakeLTRB().

◆ TEST_P() [323/454]

impeller::testing::TEST_P ( EntityTest  ,
ClipContentsOptimizesFullScreenIntersectClips   
)

Definition at line 23 of file clip_contents_unittests.cc.

23  {
24  // Set up mock environment.
25 
26  auto content_context = GetContentContext();
27  auto buffer = content_context->GetContext()->CreateCommandBuffer();
28  auto render_target =
29  GetContentContext()->GetRenderTargetCache()->CreateOffscreenMSAA(
30  *content_context->GetContext(), {100, 100},
31  /*mip_count=*/1);
32  auto render_pass = buffer->CreateRenderPass(render_target);
33  auto recording_pass = std::make_shared<RecordingRenderPass>(
34  render_pass, GetContext(), render_target);
35 
36  // Set up clip contents.
37 
38  auto contents = std::make_shared<ClipContents>();
39  contents->SetClipOperation(Entity::ClipOperation::kIntersect);
40  auto geom = Geometry::MakeCover();
41  contents->SetGeometry(geom.get());
42 
43  Entity entity;
44  entity.SetContents(std::move(contents));
45 
46  // Render the clip contents.
47 
48  ASSERT_TRUE(recording_pass->GetCommands().empty());
49  ASSERT_TRUE(entity.Render(*content_context, *recording_pass));
50  ASSERT_FALSE(recording_pass->GetCommands().empty());
51 }

References impeller::Entity::kIntersect, impeller::Geometry::MakeCover(), impeller::Entity::Render(), and impeller::Entity::SetContents().

◆ TEST_P() [324/454]

impeller::testing::TEST_P ( EntityTest  ,
ColorFilterContentsWithLargeGeometry   
)

Definition at line 2166 of file entity_unittests.cc.

2166  {
2167  Entity entity;
2168  entity.SetTransform(Matrix::MakeScale(GetContentScale()));
2169  auto src_contents = std::make_shared<SolidColorContents>();
2170  auto src_geom = Geometry::MakeRect(Rect::MakeLTRB(-300, -500, 30000, 50000));
2171  src_contents->SetGeometry(src_geom.get());
2172  src_contents->SetColor(Color::Red());
2173 
2174  auto dst_contents = std::make_shared<SolidColorContents>();
2175  auto dst_geom = Geometry::MakeRect(Rect::MakeLTRB(300, 500, 20000, 30000));
2176  dst_contents->SetGeometry(dst_geom.get());
2177  dst_contents->SetColor(Color::Blue());
2178 
2179  auto contents = ColorFilterContents::MakeBlend(
2180  BlendMode::kSourceOver, {FilterInput::Make(dst_contents, false),
2181  FilterInput::Make(src_contents, false)});
2182  entity.SetContents(std::move(contents));
2183  ASSERT_TRUE(OpenPlaygroundHere(std::move(entity)));
2184 }

References impeller::Color::Blue(), impeller::kSourceOver, impeller::FilterInput::Make(), impeller::ColorFilterContents::MakeBlend(), impeller::TRect< Scalar >::MakeLTRB(), impeller::Geometry::MakeRect(), impeller::Matrix::MakeScale(), impeller::Color::Red(), impeller::Entity::SetContents(), and impeller::Entity::SetTransform().

◆ TEST_P() [325/454]

impeller::testing::TEST_P ( EntityTest  ,
ColorFilterWithForegroundColorAdvancedBlend   
)

Definition at line 1933 of file entity_unittests.cc.

1933  {
1934  auto image = CreateTextureForFixture("boston.jpg");
1935  auto filter = ColorFilterContents::MakeBlend(
1936  BlendMode::kColorBurn, FilterInput::Make({image}), Color::Red());
1937 
1938  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
1939  Entity entity;
1940  entity.SetTransform(Matrix::MakeScale(GetContentScale()) *
1941  Matrix::MakeTranslation({500, 300}) *
1942  Matrix::MakeScale(Vector2{0.5, 0.5}));
1943  entity.SetContents(filter);
1944  return entity.Render(context, pass);
1945  };
1946  ASSERT_TRUE(OpenPlaygroundHere(callback));
1947 }

References impeller::kColorBurn, impeller::FilterInput::Make(), impeller::ColorFilterContents::MakeBlend(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeTranslation(), impeller::Color::Red(), impeller::Entity::Render(), impeller::Entity::SetContents(), and impeller::Entity::SetTransform().

◆ TEST_P() [326/454]

impeller::testing::TEST_P ( EntityTest  ,
ColorFilterWithForegroundColorClearBlend   
)

Definition at line 1949 of file entity_unittests.cc.

1949  {
1950  auto image = CreateTextureForFixture("boston.jpg");
1951  auto filter = ColorFilterContents::MakeBlend(
1952  BlendMode::kClear, FilterInput::Make({image}), Color::Red());
1953 
1954  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
1955  Entity entity;
1956  entity.SetTransform(Matrix::MakeScale(GetContentScale()) *
1957  Matrix::MakeTranslation({500, 300}) *
1958  Matrix::MakeScale(Vector2{0.5, 0.5}));
1959  entity.SetContents(filter);
1960  return entity.Render(context, pass);
1961  };
1962  ASSERT_TRUE(OpenPlaygroundHere(callback));
1963 }

References impeller::kClear, impeller::FilterInput::Make(), impeller::ColorFilterContents::MakeBlend(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeTranslation(), impeller::Color::Red(), impeller::Entity::Render(), impeller::Entity::SetContents(), and impeller::Entity::SetTransform().

◆ TEST_P() [327/454]

impeller::testing::TEST_P ( EntityTest  ,
ColorFilterWithForegroundColorDstBlend   
)

Definition at line 1981 of file entity_unittests.cc.

1981  {
1982  auto image = CreateTextureForFixture("boston.jpg");
1983  auto filter = ColorFilterContents::MakeBlend(
1984  BlendMode::kDestination, FilterInput::Make({image}), Color::Red());
1985 
1986  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
1987  Entity entity;
1988  entity.SetTransform(Matrix::MakeScale(GetContentScale()) *
1989  Matrix::MakeTranslation({500, 300}) *
1990  Matrix::MakeScale(Vector2{0.5, 0.5}));
1991  entity.SetContents(filter);
1992  return entity.Render(context, pass);
1993  };
1994  ASSERT_TRUE(OpenPlaygroundHere(callback));
1995 }

References impeller::kDestination, impeller::FilterInput::Make(), impeller::ColorFilterContents::MakeBlend(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeTranslation(), impeller::Color::Red(), impeller::Entity::Render(), impeller::Entity::SetContents(), and impeller::Entity::SetTransform().

◆ TEST_P() [328/454]

impeller::testing::TEST_P ( EntityTest  ,
ColorFilterWithForegroundColorSrcBlend   
)

Definition at line 1965 of file entity_unittests.cc.

1965  {
1966  auto image = CreateTextureForFixture("boston.jpg");
1967  auto filter = ColorFilterContents::MakeBlend(
1968  BlendMode::kSource, FilterInput::Make({image}), Color::Red());
1969 
1970  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
1971  Entity entity;
1972  entity.SetTransform(Matrix::MakeScale(GetContentScale()) *
1973  Matrix::MakeTranslation({500, 300}) *
1974  Matrix::MakeScale(Vector2{0.5, 0.5}));
1975  entity.SetContents(filter);
1976  return entity.Render(context, pass);
1977  };
1978  ASSERT_TRUE(OpenPlaygroundHere(callback));
1979 }

References impeller::kSource, impeller::FilterInput::Make(), impeller::ColorFilterContents::MakeBlend(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeTranslation(), impeller::Color::Red(), impeller::Entity::Render(), impeller::Entity::SetContents(), and impeller::Entity::SetTransform().

◆ TEST_P() [329/454]

impeller::testing::TEST_P ( EntityTest  ,
ColorFilterWithForegroundColorSrcInBlend   
)

Definition at line 1997 of file entity_unittests.cc.

1997  {
1998  auto image = CreateTextureForFixture("boston.jpg");
1999  auto filter = ColorFilterContents::MakeBlend(
2000  BlendMode::kSourceIn, FilterInput::Make({image}), Color::Red());
2001 
2002  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
2003  Entity entity;
2004  entity.SetTransform(Matrix::MakeScale(GetContentScale()) *
2005  Matrix::MakeTranslation({500, 300}) *
2006  Matrix::MakeScale(Vector2{0.5, 0.5}));
2007  entity.SetContents(filter);
2008  return entity.Render(context, pass);
2009  };
2010  ASSERT_TRUE(OpenPlaygroundHere(callback));
2011 }

References impeller::kSourceIn, impeller::FilterInput::Make(), impeller::ColorFilterContents::MakeBlend(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeTranslation(), impeller::Color::Red(), impeller::Entity::Render(), impeller::Entity::SetContents(), and impeller::Entity::SetTransform().

◆ TEST_P() [330/454]

impeller::testing::TEST_P ( EntityTest  ,
ColorMatrixFilterCoverageIsCorrect   
)

Definition at line 1448 of file entity_unittests.cc.

1448  {
1449  // Set up a simple color background.
1450  auto fill = std::make_shared<SolidColorContents>();
1451  auto geom = Geometry::MakeFillPath(
1452  PathBuilder{}.AddRect(Rect::MakeXYWH(0, 0, 300, 400)).TakePath());
1453  fill->SetGeometry(geom.get());
1454  fill->SetColor(Color::Coral());
1455 
1456  // Set the color matrix filter.
1457  ColorMatrix matrix = {
1458  1, 1, 1, 1, 1, //
1459  1, 1, 1, 1, 1, //
1460  1, 1, 1, 1, 1, //
1461  1, 1, 1, 1, 1, //
1462  };
1463 
1464  auto filter =
1465  ColorFilterContents::MakeColorMatrix(FilterInput::Make(fill), matrix);
1466 
1467  Entity e;
1468  e.SetTransform(Matrix());
1469 
1470  // Confirm that the actual filter coverage matches the expected coverage.
1471  auto actual = filter->GetCoverage(e);
1472  auto expected = Rect::MakeXYWH(0, 0, 300, 400);
1473 
1474  ASSERT_TRUE(actual.has_value());
1475  ASSERT_RECT_NEAR(actual.value(), expected);
1476 }

References impeller::PathBuilder::AddRect(), ASSERT_RECT_NEAR, impeller::Color::Coral(), impeller::FilterInput::Make(), impeller::ColorFilterContents::MakeColorMatrix(), impeller::Geometry::MakeFillPath(), impeller::TRect< Scalar >::MakeXYWH(), and impeller::Entity::SetTransform().

◆ TEST_P() [331/454]

impeller::testing::TEST_P ( EntityTest  ,
ColorMatrixFilterEditable   
)

Definition at line 1478 of file entity_unittests.cc.

1478  {
1479  auto bay_bridge = CreateTextureForFixture("bay_bridge.jpg");
1480  ASSERT_TRUE(bay_bridge);
1481 
1482  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
1483  // UI state.
1484  static ColorMatrix color_matrix = {
1485  1, 0, 0, 0, 0, //
1486  0, 3, 0, 0, 0, //
1487  0, 0, 1, 0, 0, //
1488  0, 0, 0, 1, 0, //
1489  };
1490  static float offset[2] = {500, 400};
1491  static float rotation = 0;
1492  static float scale[2] = {0.65, 0.65};
1493  static float skew[2] = {0, 0};
1494 
1495  // Define the ImGui
1496  ImGui::Begin("Color Matrix", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
1497  {
1498  std::string label = "##1";
1499  for (int i = 0; i < 20; i += 5) {
1500  ImGui::InputScalarN(label.c_str(), ImGuiDataType_Float,
1501  &(color_matrix.array[i]), 5, nullptr, nullptr,
1502  "%.2f", 0);
1503  label[2]++;
1504  }
1505 
1506  ImGui::SliderFloat2("Translation", &offset[0], 0,
1507  pass.GetRenderTargetSize().width);
1508  ImGui::SliderFloat("Rotation", &rotation, 0, kPi * 2);
1509  ImGui::SliderFloat2("Scale", &scale[0], 0, 3);
1510  ImGui::SliderFloat2("Skew", &skew[0], -3, 3);
1511  }
1512  ImGui::End();
1513 
1514  // Set the color matrix filter.
1515  auto filter = ColorFilterContents::MakeColorMatrix(
1516  FilterInput::Make(bay_bridge), color_matrix);
1517 
1518  // Define the entity with the color matrix filter.
1519  Entity entity;
1520  entity.SetTransform(
1521  Matrix::MakeScale(GetContentScale()) *
1522  Matrix::MakeTranslation(Vector3(offset[0], offset[1])) *
1523  Matrix::MakeRotationZ(Radians(rotation)) *
1524  Matrix::MakeScale(Vector2(scale[0], scale[1])) *
1525  Matrix::MakeSkew(skew[0], skew[1]) *
1526  Matrix::MakeTranslation(-Point(bay_bridge->GetSize()) / 2));
1527  entity.SetContents(filter);
1528  entity.Render(context, pass);
1529 
1530  return true;
1531  };
1532 
1533  ASSERT_TRUE(OpenPlaygroundHere(callback));
1534 }

References impeller::ColorMatrix::array, impeller::kPi, impeller::FilterInput::Make(), impeller::ColorFilterContents::MakeColorMatrix(), impeller::Matrix::MakeRotationZ(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeSkew(), impeller::Matrix::MakeTranslation(), offset, impeller::Entity::Render(), scale, impeller::Entity::SetContents(), and impeller::Entity::SetTransform().

◆ TEST_P() [332/454]

impeller::testing::TEST_P ( EntityTest  ,
ConicalGradientContentsIsOpaque   
)

Definition at line 2054 of file entity_unittests.cc.

2054  {
2055  Matrix matrix;
2056  ConicalGradientContents contents;
2057  auto geom = Geometry::MakeRect(Rect::MakeLTRB(0, 0, 10, 10));
2058  contents.SetGeometry(geom.get());
2059 
2060  contents.SetColors({Color::CornflowerBlue()});
2061  EXPECT_FALSE(contents.IsOpaque(matrix));
2062  contents.SetColors({Color::CornflowerBlue().WithAlpha(0.5)});
2063  EXPECT_FALSE(contents.IsOpaque(matrix));
2064 
2065  // Create stroked path that required alpha coverage.
2066  geom = Geometry::MakeStrokePath(
2067  PathBuilder{}.AddLine({0, 0}, {100, 100}).TakePath(),
2068  /*stroke_width=*/0.05);
2069  contents.SetGeometry(geom.get());
2070  contents.SetColors({Color::CornflowerBlue()});
2071 
2072  EXPECT_FALSE(contents.IsOpaque(matrix));
2073 }

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() [333/454]

impeller::testing::TEST_P ( EntityTest  ,
ContentContextOptionsHasReasonableHashFunctions   
)

Definition at line 2233 of file entity_unittests.cc.

2233  {
2234  ContentContextOptions opts;
2235  auto hash_a = ContentContextOptions::Hash{}(opts);
2236 
2237  opts.blend_mode = BlendMode::kColorBurn;
2238  auto hash_b = ContentContextOptions::Hash{}(opts);
2239 
2240  opts.has_depth_stencil_attachments = false;
2241  auto hash_c = ContentContextOptions::Hash{}(opts);
2242 
2243  opts.primitive_type = PrimitiveType::kPoint;
2244  auto hash_d = ContentContextOptions::Hash{}(opts);
2245 
2246  EXPECT_NE(hash_a, hash_b);
2247  EXPECT_NE(hash_b, hash_c);
2248  EXPECT_NE(hash_c, hash_d);
2249 }

References impeller::ContentContextOptions::blend_mode, impeller::ContentContextOptions::has_depth_stencil_attachments, impeller::kColorBurn, impeller::kPoint, and impeller::ContentContextOptions::primitive_type.

◆ TEST_P() [334/454]

impeller::testing::TEST_P ( EntityTest  ,
ContentsGetBoundsForEmptyPathReturnsNullopt   
)

Definition at line 1195 of file entity_unittests.cc.

1195  {
1196  Entity entity;
1197  entity.SetContents(std::make_shared<SolidColorContents>());
1198  ASSERT_FALSE(entity.GetCoverage().has_value());
1199 }

References impeller::Entity::GetCoverage(), and impeller::Entity::SetContents().

◆ TEST_P() [335/454]

impeller::testing::TEST_P ( EntityTest  ,
CoverageForStrokePathWithNegativeValuesInTransform   
)

Definition at line 2013 of file entity_unittests.cc.

2013  {
2014  auto arrow_head = PathBuilder{}
2015  .MoveTo({50, 120})
2016  .LineTo({120, 190})
2017  .LineTo({190, 120})
2018  .TakePath();
2019  auto geometry = Geometry::MakeStrokePath(arrow_head, 15.0, 4.0, Cap::kRound,
2020  Join::kRound);
2021 
2022  auto transform = Matrix::MakeTranslation({300, 300}) *
2023  Matrix::MakeRotationZ(Radians(kPiOver2));
2024  // Note that e[0][0] used to be tested here, but it was -epsilon solely
2025  // due to floating point inaccuracy in the transcendental trig functions.
2026  // e[1][0] is the intended negative value that we care about (-1.0) as it
2027  // comes from the rotation of pi/2.
2028  EXPECT_LT(transform.e[1][0], 0.0f);
2029  auto coverage = geometry->GetCoverage(transform);
2030  ASSERT_RECT_NEAR(coverage.value(), Rect::MakeXYWH(102.5, 342.5, 85, 155));
2031 }

References ASSERT_RECT_NEAR, impeller::kPiOver2, impeller::kRound, impeller::LineTo(), impeller::Matrix::MakeRotationZ(), impeller::Geometry::MakeStrokePath(), impeller::Matrix::MakeTranslation(), impeller::TRect< Scalar >::MakeXYWH(), impeller::PathBuilder::MoveTo(), and transform.

◆ TEST_P() [336/454]

impeller::testing::TEST_P ( EntityTest  ,
CubicCurveAndOverlapTest   
)

Definition at line 420 of file entity_unittests.cc.

420  {
421  // Compare with https://fiddle.skia.org/c/7a05a3e186c65a8dfb732f68020aae06
422  Path path =
423  PathBuilder{}
424  .MoveTo({359.934, 96.6335})
425  .CubicCurveTo({358.189, 96.7055}, {356.436, 96.7908},
426  {354.673, 96.8895})
427  .CubicCurveTo({354.571, 96.8953}, {354.469, 96.9016},
428  {354.367, 96.9075})
429  .CubicCurveTo({352.672, 97.0038}, {350.969, 97.113},
430  {349.259, 97.2355})
431  .CubicCurveTo({349.048, 97.2506}, {348.836, 97.2678},
432  {348.625, 97.2834})
433  .CubicCurveTo({347.019, 97.4014}, {345.407, 97.5299},
434  {343.789, 97.6722})
435  .CubicCurveTo({343.428, 97.704}, {343.065, 97.7402},
436  {342.703, 97.7734})
437  .CubicCurveTo({341.221, 97.9086}, {339.736, 98.0505},
438  {338.246, 98.207})
439  .CubicCurveTo({337.702, 98.2642}, {337.156, 98.3292},
440  {336.612, 98.3894})
441  .CubicCurveTo({335.284, 98.5356}, {333.956, 98.6837},
442  {332.623, 98.8476})
443  .CubicCurveTo({332.495, 98.8635}, {332.366, 98.8818},
444  {332.237, 98.8982})
445  .LineTo({332.237, 102.601})
446  .LineTo({321.778, 102.601})
447  .LineTo({321.778, 100.382})
448  .CubicCurveTo({321.572, 100.413}, {321.367, 100.442},
449  {321.161, 100.476})
450  .CubicCurveTo({319.22, 100.79}, {317.277, 101.123},
451  {315.332, 101.479})
452  .CubicCurveTo({315.322, 101.481}, {315.311, 101.482},
453  {315.301, 101.484})
454  .LineTo({310.017, 105.94})
455  .LineTo({309.779, 105.427})
456  .LineTo({314.403, 101.651})
457  .CubicCurveTo({314.391, 101.653}, {314.379, 101.656},
458  {314.368, 101.658})
459  .CubicCurveTo({312.528, 102.001}, {310.687, 102.366},
460  {308.846, 102.748})
461  .CubicCurveTo({307.85, 102.955}, {306.855, 103.182}, {305.859, 103.4})
462  .CubicCurveTo({305.048, 103.579}, {304.236, 103.75},
463  {303.425, 103.936})
464  .LineTo({299.105, 107.578})
465  .LineTo({298.867, 107.065})
466  .LineTo({302.394, 104.185})
467  .LineTo({302.412, 104.171})
468  .CubicCurveTo({301.388, 104.409}, {300.366, 104.67},
469  {299.344, 104.921})
470  .CubicCurveTo({298.618, 105.1}, {297.89, 105.269}, {297.165, 105.455})
471  .CubicCurveTo({295.262, 105.94}, {293.36, 106.445},
472  {291.462, 106.979})
473  .CubicCurveTo({291.132, 107.072}, {290.802, 107.163},
474  {290.471, 107.257})
475  .CubicCurveTo({289.463, 107.544}, {288.455, 107.839},
476  {287.449, 108.139})
477  .CubicCurveTo({286.476, 108.431}, {285.506, 108.73},
478  {284.536, 109.035})
479  .CubicCurveTo({283.674, 109.304}, {282.812, 109.579},
480  {281.952, 109.859})
481  .CubicCurveTo({281.177, 110.112}, {280.406, 110.377},
482  {279.633, 110.638})
483  .CubicCurveTo({278.458, 111.037}, {277.256, 111.449},
484  {276.803, 111.607})
485  .CubicCurveTo({276.76, 111.622}, {276.716, 111.637},
486  {276.672, 111.653})
487  .CubicCurveTo({275.017, 112.239}, {273.365, 112.836},
488  {271.721, 113.463})
489  .LineTo({271.717, 113.449})
490  .CubicCurveTo({271.496, 113.496}, {271.238, 113.559},
491  {270.963, 113.628})
492  .CubicCurveTo({270.893, 113.645}, {270.822, 113.663},
493  {270.748, 113.682})
494  .CubicCurveTo({270.468, 113.755}, {270.169, 113.834},
495  {269.839, 113.926})
496  .CubicCurveTo({269.789, 113.94}, {269.732, 113.957},
497  {269.681, 113.972})
498  .CubicCurveTo({269.391, 114.053}, {269.081, 114.143},
499  {268.756, 114.239})
500  .CubicCurveTo({268.628, 114.276}, {268.5, 114.314},
501  {268.367, 114.354})
502  .CubicCurveTo({268.172, 114.412}, {267.959, 114.478},
503  {267.752, 114.54})
504  .CubicCurveTo({263.349, 115.964}, {258.058, 117.695},
505  {253.564, 119.252})
506  .CubicCurveTo({253.556, 119.255}, {253.547, 119.258},
507  {253.538, 119.261})
508  .CubicCurveTo({251.844, 119.849}, {250.056, 120.474},
509  {248.189, 121.131})
510  .CubicCurveTo({248, 121.197}, {247.812, 121.264}, {247.621, 121.331})
511  .CubicCurveTo({247.079, 121.522}, {246.531, 121.715},
512  {245.975, 121.912})
513  .CubicCurveTo({245.554, 122.06}, {245.126, 122.212},
514  {244.698, 122.364})
515  .CubicCurveTo({244.071, 122.586}, {243.437, 122.811},
516  {242.794, 123.04})
517  .CubicCurveTo({242.189, 123.255}, {241.58, 123.472},
518  {240.961, 123.693})
519  .CubicCurveTo({240.659, 123.801}, {240.357, 123.909},
520  {240.052, 124.018})
521  .CubicCurveTo({239.12, 124.351}, {238.18, 124.687}, {237.22, 125.032})
522  .LineTo({237.164, 125.003})
523  .CubicCurveTo({236.709, 125.184}, {236.262, 125.358},
524  {235.81, 125.538})
525  .CubicCurveTo({235.413, 125.68}, {234.994, 125.832},
526  {234.592, 125.977})
527  .CubicCurveTo({234.592, 125.977}, {234.591, 125.977},
528  {234.59, 125.977})
529  .CubicCurveTo({222.206, 130.435}, {207.708, 135.753},
530  {192.381, 141.429})
531  .CubicCurveTo({162.77, 151.336}, {122.17, 156.894}, {84.1123, 160})
532  .LineTo({360, 160})
533  .LineTo({360, 119.256})
534  .LineTo({360, 106.332})
535  .LineTo({360, 96.6307})
536  .CubicCurveTo({359.978, 96.6317}, {359.956, 96.6326},
537  {359.934, 96.6335})
538  .Close()
539  .MoveTo({337.336, 124.143})
540  .CubicCurveTo({337.274, 122.359}, {338.903, 121.511},
541  {338.903, 121.511})
542  .CubicCurveTo({338.903, 121.511}, {338.96, 123.303},
543  {337.336, 124.143})
544  .Close()
545  .MoveTo({340.082, 121.849})
546  .CubicCurveTo({340.074, 121.917}, {340.062, 121.992},
547  {340.046, 122.075})
548  .CubicCurveTo({340.039, 122.109}, {340.031, 122.142},
549  {340.023, 122.177})
550  .CubicCurveTo({340.005, 122.26}, {339.98, 122.346},
551  {339.952, 122.437})
552  .CubicCurveTo({339.941, 122.473}, {339.931, 122.507},
553  {339.918, 122.544})
554  .CubicCurveTo({339.873, 122.672}, {339.819, 122.804},
555  {339.75, 122.938})
556  .CubicCurveTo({339.747, 122.944}, {339.743, 122.949},
557  {339.74, 122.955})
558  .CubicCurveTo({339.674, 123.08}, {339.593, 123.205},
559  {339.501, 123.328})
560  .CubicCurveTo({339.473, 123.366}, {339.441, 123.401},
561  {339.41, 123.438})
562  .CubicCurveTo({339.332, 123.534}, {339.243, 123.625},
563  {339.145, 123.714})
564  .CubicCurveTo({339.105, 123.75}, {339.068, 123.786},
565  {339.025, 123.821})
566  .CubicCurveTo({338.881, 123.937}, {338.724, 124.048},
567  {338.539, 124.143})
568  .CubicCurveTo({338.532, 123.959}, {338.554, 123.79},
569  {338.58, 123.626})
570  .CubicCurveTo({338.58, 123.625}, {338.58, 123.625}, {338.58, 123.625})
571  .CubicCurveTo({338.607, 123.455}, {338.65, 123.299},
572  {338.704, 123.151})
573  .CubicCurveTo({338.708, 123.14}, {338.71, 123.127},
574  {338.714, 123.117})
575  .CubicCurveTo({338.769, 122.971}, {338.833, 122.838},
576  {338.905, 122.712})
577  .CubicCurveTo({338.911, 122.702}, {338.916, 122.69200000000001},
578  {338.922, 122.682})
579  .CubicCurveTo({338.996, 122.557}, {339.072, 122.444},
580  {339.155, 122.34})
581  .CubicCurveTo({339.161, 122.333}, {339.166, 122.326},
582  {339.172, 122.319})
583  .CubicCurveTo({339.256, 122.215}, {339.339, 122.12},
584  {339.425, 122.037})
585  .CubicCurveTo({339.428, 122.033}, {339.431, 122.03},
586  {339.435, 122.027})
587  .CubicCurveTo({339.785, 121.687}, {340.106, 121.511},
588  {340.106, 121.511})
589  .CubicCurveTo({340.106, 121.511}, {340.107, 121.645},
590  {340.082, 121.849})
591  .Close()
592  .MoveTo({340.678, 113.245})
593  .CubicCurveTo({340.594, 113.488}, {340.356, 113.655},
594  {340.135, 113.775})
595  .CubicCurveTo({339.817, 113.948}, {339.465, 114.059},
596  {339.115, 114.151})
597  .CubicCurveTo({338.251, 114.379}, {337.34, 114.516},
598  {336.448, 114.516})
599  .CubicCurveTo({335.761, 114.516}, {335.072, 114.527},
600  {334.384, 114.513})
601  .CubicCurveTo({334.125, 114.508}, {333.862, 114.462},
602  {333.605, 114.424})
603  .CubicCurveTo({332.865, 114.318}, {332.096, 114.184},
604  {331.41, 113.883})
605  .CubicCurveTo({330.979, 113.695}, {330.442, 113.34},
606  {330.672, 112.813})
607  .CubicCurveTo({331.135, 111.755}, {333.219, 112.946},
608  {334.526, 113.833})
609  .CubicCurveTo({334.54, 113.816}, {334.554, 113.8}, {334.569, 113.784})
610  .CubicCurveTo({333.38, 112.708}, {331.749, 110.985},
611  {332.76, 110.402})
612  .CubicCurveTo({333.769, 109.82}, {334.713, 111.93},
613  {335.228, 113.395})
614  .CubicCurveTo({334.915, 111.889}, {334.59, 109.636},
615  {335.661, 109.592})
616  .CubicCurveTo({336.733, 109.636}, {336.408, 111.889},
617  {336.07, 113.389})
618  .CubicCurveTo({336.609, 111.93}, {337.553, 109.82},
619  {338.563, 110.402})
620  .CubicCurveTo({339.574, 110.984}, {337.942, 112.708},
621  {336.753, 113.784})
622  .CubicCurveTo({336.768, 113.8}, {336.782, 113.816},
623  {336.796, 113.833})
624  .CubicCurveTo({338.104, 112.946}, {340.187, 111.755},
625  {340.65, 112.813})
626  .CubicCurveTo({340.71, 112.95}, {340.728, 113.102},
627  {340.678, 113.245})
628  .Close()
629  .MoveTo({346.357, 106.771})
630  .CubicCurveTo({346.295, 104.987}, {347.924, 104.139},
631  {347.924, 104.139})
632  .CubicCurveTo({347.924, 104.139}, {347.982, 105.931},
633  {346.357, 106.771})
634  .Close()
635  .MoveTo({347.56, 106.771})
636  .CubicCurveTo({347.498, 104.987}, {349.127, 104.139},
637  {349.127, 104.139})
638  .CubicCurveTo({349.127, 104.139}, {349.185, 105.931},
639  {347.56, 106.771})
640  .Close()
641  .TakePath();
642  Entity entity;
643  entity.SetTransform(Matrix::MakeScale(GetContentScale()));
644 
645  static std::unique_ptr<Geometry> geom = Geometry::MakeFillPath(path);
646 
647  auto contents = std::make_shared<SolidColorContents>();
648  contents->SetColor(Color::Red());
649  contents->SetGeometry(geom.get());
650 
651  entity.SetContents(contents);
652  ASSERT_TRUE(OpenPlaygroundHere(std::move(entity)));
653 }

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() [337/454]

impeller::testing::TEST_P ( EntityTest  ,
CubicCurveTest   
)

Definition at line 338 of file entity_unittests.cc.

338  {
339  // Compare with https://fiddle.skia.org/c/b3625f26122c9de7afe7794fcf25ead3
340  Path path =
341  PathBuilder{}
342  .MoveTo({237.164, 125.003})
343  .CubicCurveTo({236.709, 125.184}, {236.262, 125.358},
344  {235.81, 125.538})
345  .CubicCurveTo({235.413, 125.68}, {234.994, 125.832},
346  {234.592, 125.977})
347  .CubicCurveTo({234.592, 125.977}, {234.591, 125.977},
348  {234.59, 125.977})
349  .CubicCurveTo({222.206, 130.435}, {207.708, 135.753},
350  {192.381, 141.429})
351  .CubicCurveTo({162.77, 151.336}, {122.17, 156.894}, {84.1123, 160})
352  .Close()
353  .TakePath();
354  Entity entity;
355  entity.SetTransform(Matrix::MakeScale(GetContentScale()));
356 
357  static std::unique_ptr<Geometry> geom = Geometry::MakeFillPath(path);
358 
359  auto contents = std::make_shared<SolidColorContents>();
360  contents->SetColor(Color::Red());
361  contents->SetGeometry(geom.get());
362 
363  entity.SetContents(contents);
364  ASSERT_TRUE(OpenPlaygroundHere(std::move(entity)));
365 }

References impeller::Close(), impeller::Geometry::MakeFillPath(), impeller::Matrix::MakeScale(), impeller::PathBuilder::MoveTo(), impeller::Color::Red(), impeller::Entity::SetContents(), and impeller::Entity::SetTransform().

◆ TEST_P() [338/454]

impeller::testing::TEST_P ( EntityTest  ,
DecalSpecializationAppliedToMorphologyFilter   
)

Definition at line 2217 of file entity_unittests.cc.

2217  {
2218  auto content_context = GetContentContext();
2219  auto default_color_burn = content_context->GetMorphologyFilterPipeline({
2220  .color_attachment_pixel_format = PixelFormat::kR8G8B8A8UNormInt,
2221  });
2222 
2223  auto decal_supported = static_cast<Scalar>(
2224  GetContext()->GetCapabilities()->SupportsDecalSamplerAddressMode());
2225  std::vector<Scalar> expected_constants = {decal_supported};
2226  ASSERT_EQ(default_color_burn->GetDescriptor().GetSpecializationConstants(),
2227  expected_constants);
2228 }

References impeller::kR8G8B8A8UNormInt.

◆ TEST_P() [339/454]

impeller::testing::TEST_P ( EntityTest  ,
DrawSuperEllipse   
)

Definition at line 2366 of file entity_unittests.cc.

2366  {
2367  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
2368  // UI state.
2369  static float alpha = 10;
2370  static float beta = 10;
2371  static float radius = 40;
2372  static int degree = 4;
2373  static Color color = Color::Red();
2374 
2375  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
2376  ImGui::SliderFloat("Alpha", &alpha, 0, 100);
2377  ImGui::SliderFloat("Beta", &beta, 0, 100);
2378  ImGui::SliderInt("Degreee", &degree, 1, 20);
2379  ImGui::SliderFloat("Radius", &radius, 0, 400);
2380  ImGui::ColorEdit4("Color", reinterpret_cast<float*>(&color));
2381  ImGui::End();
2382 
2383  auto contents = std::make_shared<SolidColorContents>();
2384  static std::unique_ptr<SuperellipseGeometry> geom =
2385  std::make_unique<SuperellipseGeometry>(Point{400, 400}, radius, degree,
2386  alpha, beta);
2387  contents->SetColor(color);
2388  contents->SetGeometry(geom.get());
2389 
2390  Entity entity;
2391  entity.SetContents(contents);
2392 
2393  return entity.Render(context, pass);
2394  };
2395 
2396  ASSERT_TRUE(OpenPlaygroundHere(callback));
2397 }

References color, impeller::Color::Red(), impeller::Entity::Render(), and impeller::Entity::SetContents().

◆ TEST_P() [340/454]

impeller::testing::TEST_P ( EntityTest  ,
FailOnValidationError   
)

Definition at line 2311 of file entity_unittests.cc.

2311  {
2312  if (GetParam() != PlaygroundBackend::kVulkan) {
2313  GTEST_SKIP() << "Validation is only fatal on Vulkan backend.";
2314  }
2315  EXPECT_DEATH(
2316  // The easiest way to trigger a validation error is to try to compile
2317  // a shader with an unsupported pixel format.
2318  GetContentContext()->GetBlendColorBurnPipeline({
2319  .color_attachment_pixel_format = PixelFormat::kUnknown,
2320  .has_depth_stencil_attachments = false,
2321  }),
2322  "");
2323 }

References impeller::kUnknown, and impeller::kVulkan.

◆ TEST_P() [341/454]

impeller::testing::TEST_P ( EntityTest  ,
FillPathGeometryGetPositionBufferReturnsExpectedMode   
)

Definition at line 2277 of file entity_unittests.cc.

2277  {
2278  RenderTarget target;
2279  testing::MockRenderPass mock_pass(GetContext(), target);
2280 
2281  auto get_result = [this, &mock_pass](const Path& path) {
2282  auto geometry = Geometry::MakeFillPath(
2283  path, /* inner rect */ Rect::MakeLTRB(0, 0, 100, 100));
2284  return geometry->GetPositionBuffer(*GetContentContext(), {}, mock_pass);
2285  };
2286 
2287  // Convex path
2288  {
2289  GeometryResult result =
2290  get_result(PathBuilder{}
2291  .AddRect(Rect::MakeLTRB(0, 0, 100, 100))
2292  .SetConvexity(Convexity::kConvex)
2293  .TakePath());
2294  EXPECT_EQ(result.mode, GeometryResult::Mode::kNormal);
2295  }
2296 
2297  // Concave path
2298  {
2299  Path path = PathBuilder{}
2300  .MoveTo({0, 0})
2301  .LineTo({100, 0})
2302  .LineTo({100, 100})
2303  .LineTo({50, 50})
2304  .Close()
2305  .TakePath();
2306  GeometryResult result = get_result(path);
2307  EXPECT_EQ(result.mode, GeometryResult::Mode::kNonZero);
2308  }
2309 }

References impeller::PathBuilder::AddRect(), impeller::Close(), impeller::kConvex, impeller::GeometryResult::kNonZero, impeller::GeometryResult::kNormal, impeller::LineTo(), impeller::Geometry::MakeFillPath(), impeller::TRect< Scalar >::MakeLTRB(), impeller::GeometryResult::mode, and impeller::PathBuilder::MoveTo().

◆ TEST_P() [342/454]

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() [343/454]

impeller::testing::TEST_P ( EntityTest  ,
Filters   
)

Definition at line 871 of file entity_unittests.cc.

871  {
872  auto bridge = CreateTextureForFixture("bay_bridge.jpg");
873  auto boston = CreateTextureForFixture("boston.jpg");
874  auto kalimba = CreateTextureForFixture("kalimba.jpg");
875  ASSERT_TRUE(bridge && boston && kalimba);
876 
877  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
878  auto fi_bridge = FilterInput::Make(bridge);
879  auto fi_boston = FilterInput::Make(boston);
880  auto fi_kalimba = FilterInput::Make(kalimba);
881 
882  std::shared_ptr<FilterContents> blend0 = ColorFilterContents::MakeBlend(
883  BlendMode::kModulate, {fi_kalimba, fi_boston});
884 
885  auto blend1 = ColorFilterContents::MakeBlend(
886  BlendMode::kScreen,
887  {FilterInput::Make(blend0), fi_bridge, fi_bridge, fi_bridge});
888 
889  Entity entity;
890  entity.SetTransform(Matrix::MakeScale(GetContentScale()) *
891  Matrix::MakeTranslation({500, 300}) *
892  Matrix::MakeScale(Vector2{0.5, 0.5}));
893  entity.SetContents(blend1);
894  return entity.Render(context, pass);
895  };
896  ASSERT_TRUE(OpenPlaygroundHere(callback));
897 }

References impeller::kModulate, impeller::kScreen, impeller::FilterInput::Make(), impeller::ColorFilterContents::MakeBlend(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeTranslation(), and impeller::Entity::SetTransform().

◆ TEST_P() [344/454]

impeller::testing::TEST_P ( EntityTest  ,
GaussianBlurFilter   
)

Definition at line 899 of file entity_unittests.cc.

899  {
900  auto boston =
901  CreateTextureForFixture("boston.jpg", /*enable_mipmapping=*/true);
902  ASSERT_TRUE(boston);
903 
904  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
905  const char* input_type_names[] = {"Texture", "Solid Color"};
906  const char* blur_type_names[] = {"Image blur", "Mask blur"};
907  const char* pass_variation_names[] = {"New"};
908  const char* blur_style_names[] = {"Normal", "Solid", "Outer", "Inner"};
909  const char* tile_mode_names[] = {"Clamp", "Repeat", "Mirror", "Decal"};
910  const FilterContents::BlurStyle blur_styles[] = {
911  FilterContents::BlurStyle::kNormal, FilterContents::BlurStyle::kSolid,
912  FilterContents::BlurStyle::kOuter, FilterContents::BlurStyle::kInner};
913  const Entity::TileMode tile_modes[] = {
914  Entity::TileMode::kClamp, Entity::TileMode::kRepeat,
915  Entity::TileMode::kMirror, Entity::TileMode::kDecal};
916 
917  // UI state.
918  static int selected_input_type = 0;
919  static Color input_color = Color::Black();
920  static int selected_blur_type = 0;
921  static int selected_pass_variation = 0;
922  static bool combined_sigma = false;
923  static float blur_amount_coarse[2] = {0, 0};
924  static float blur_amount_fine[2] = {10, 10};
925  static int selected_blur_style = 0;
926  static int selected_tile_mode = 3;
927  static Color cover_color(1, 0, 0, 0.2);
928  static Color bounds_color(0, 1, 0, 0.1);
929  static float offset[2] = {500, 400};
930  static float rotation = 0;
931  static float scale[2] = {0.65, 0.65};
932  static float skew[2] = {0, 0};
933  static float path_rect[4] = {0, 0,
934  static_cast<float>(boston->GetSize().width),
935  static_cast<float>(boston->GetSize().height)};
936 
937  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
938  {
939  ImGui::Combo("Input type", &selected_input_type, input_type_names,
940  sizeof(input_type_names) / sizeof(char*));
941  if (selected_input_type == 0) {
942  ImGui::SliderFloat("Input opacity", &input_color.alpha, 0, 1);
943  } else {
944  ImGui::ColorEdit4("Input color",
945  reinterpret_cast<float*>(&input_color));
946  }
947  ImGui::Combo("Blur type", &selected_blur_type, blur_type_names,
948  sizeof(blur_type_names) / sizeof(char*));
949  if (selected_blur_type == 0) {
950  ImGui::Combo("Pass variation", &selected_pass_variation,
951  pass_variation_names,
952  sizeof(pass_variation_names) / sizeof(char*));
953  }
954  ImGui::Checkbox("Combined sigma", &combined_sigma);
955  if (combined_sigma) {
956  ImGui::SliderFloat("Sigma (coarse)", blur_amount_coarse, 0, 1000);
957  ImGui::SliderFloat("Sigma (fine)", blur_amount_fine, 0, 10);
958  blur_amount_coarse[1] = blur_amount_coarse[0];
959  blur_amount_fine[1] = blur_amount_fine[0];
960  } else {
961  ImGui::SliderFloat2("Sigma (coarse)", blur_amount_coarse, 0, 1000);
962  ImGui::SliderFloat2("Sigma (fine)", blur_amount_fine, 0, 10);
963  }
964  ImGui::Combo("Blur style", &selected_blur_style, blur_style_names,
965  sizeof(blur_style_names) / sizeof(char*));
966  ImGui::Combo("Tile mode", &selected_tile_mode, tile_mode_names,
967  sizeof(tile_mode_names) / sizeof(char*));
968  ImGui::ColorEdit4("Cover color", reinterpret_cast<float*>(&cover_color));
969  ImGui::ColorEdit4("Bounds color ",
970  reinterpret_cast<float*>(&bounds_color));
971  ImGui::SliderFloat2("Translation", offset, 0,
972  pass.GetRenderTargetSize().width);
973  ImGui::SliderFloat("Rotation", &rotation, 0, kPi * 2);
974  ImGui::SliderFloat2("Scale", scale, 0, 3);
975  ImGui::SliderFloat2("Skew", skew, -3, 3);
976  ImGui::SliderFloat4("Path XYWH", path_rect, -1000, 1000);
977  }
978  ImGui::End();
979 
980  auto blur_sigma_x = Sigma{blur_amount_coarse[0] + blur_amount_fine[0]};
981  auto blur_sigma_y = Sigma{blur_amount_coarse[1] + blur_amount_fine[1]};
982 
983  std::shared_ptr<Contents> input;
984  Size input_size;
985 
986  auto input_rect =
987  Rect::MakeXYWH(path_rect[0], path_rect[1], path_rect[2], path_rect[3]);
988  if (selected_input_type == 0) {
989  auto texture = std::make_shared<TextureContents>();
990  texture->SetSourceRect(Rect::MakeSize(boston->GetSize()));
991  texture->SetDestinationRect(input_rect);
992  texture->SetTexture(boston);
993  texture->SetOpacity(input_color.alpha);
994 
995  input = texture;
996  input_size = input_rect.GetSize();
997  } else {
998  auto fill = std::make_shared<SolidColorContents>();
999  fill->SetColor(input_color);
1000  static std::unique_ptr<Geometry> geom =
1001  Geometry::MakeFillPath(PathBuilder{}.AddRect(input_rect).TakePath());
1002 
1003  fill->SetGeometry(geom.get());
1004 
1005  input = fill;
1006  input_size = input_rect.GetSize();
1007  }
1008 
1009  std::shared_ptr<FilterContents> blur;
1010  switch (selected_pass_variation) {
1011  case 0:
1012  blur = std::make_shared<GaussianBlurFilterContents>(
1013  blur_sigma_x.sigma, blur_sigma_y.sigma,
1014  tile_modes[selected_tile_mode], blur_styles[selected_blur_style],
1015  /*geometry=*/nullptr);
1016  blur->SetInputs({FilterInput::Make(input)});
1017  break;
1018  case 1:
1019  blur = FilterContents::MakeGaussianBlur(
1020  FilterInput::Make(input), blur_sigma_x, blur_sigma_y,
1021  tile_modes[selected_tile_mode], blur_styles[selected_blur_style]);
1022  break;
1023  };
1024  FML_CHECK(blur);
1025 
1026  auto mask_blur = FilterContents::MakeBorderMaskBlur(
1027  FilterInput::Make(input), blur_sigma_x, blur_sigma_y,
1028  blur_styles[selected_blur_style]);
1029 
1030  auto ctm = Matrix::MakeScale(GetContentScale()) *
1031  Matrix::MakeTranslation(Vector3(offset[0], offset[1])) *
1032  Matrix::MakeRotationZ(Radians(rotation)) *
1033  Matrix::MakeScale(Vector2(scale[0], scale[1])) *
1034  Matrix::MakeSkew(skew[0], skew[1]) *
1035  Matrix::MakeTranslation(-Point(input_size) / 2);
1036 
1037  auto target_contents = selected_blur_type == 0 ? blur : mask_blur;
1038 
1039  Entity entity;
1040  entity.SetContents(target_contents);
1041  entity.SetTransform(ctm);
1042 
1043  entity.Render(context, pass);
1044 
1045  // Renders a red "cover" rectangle that shows the original position of the
1046  // unfiltered input.
1047  Entity cover_entity;
1048  static std::unique_ptr<Geometry> geom =
1049  Geometry::MakeFillPath(PathBuilder{}.AddRect(input_rect).TakePath());
1050  auto contents = std::make_shared<SolidColorContents>();
1051  contents->SetColor(cover_color);
1052  contents->SetGeometry(geom.get());
1053  cover_entity.SetContents(std::move(contents));
1054  cover_entity.SetTransform(ctm);
1055  cover_entity.Render(context, pass);
1056 
1057  // Renders a green bounding rect of the target filter.
1058  Entity bounds_entity;
1059  std::optional<Rect> target_contents_coverage =
1060  target_contents->GetCoverage(entity);
1061  if (target_contents_coverage.has_value()) {
1062  static std::unique_ptr<Geometry> geom = Geometry::MakeFillPath(
1063  PathBuilder{}
1064  .AddRect(target_contents->GetCoverage(entity).value())
1065  .TakePath());
1066  auto contents = std::make_shared<SolidColorContents>();
1067  contents->SetColor(bounds_color);
1068  contents->SetGeometry(geom.get());
1069 
1070  bounds_entity.SetContents(contents);
1071  bounds_entity.SetTransform(Matrix());
1072  bounds_entity.Render(context, pass);
1073  }
1074 
1075  return true;
1076  };
1077  ASSERT_TRUE(OpenPlaygroundHere(callback));
1078 }

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() [345/454]

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() [346/454]

impeller::testing::TEST_P ( EntityTest  ,
LinearGradientContentsIsOpaque   
)

Definition at line 2075 of file entity_unittests.cc.

2075  {
2076  Matrix matrix;
2077  LinearGradientContents contents;
2078  auto geom = Geometry::MakeRect(Rect::MakeLTRB(0, 0, 10, 10));
2079  contents.SetGeometry(geom.get());
2080 
2081  contents.SetColors({Color::CornflowerBlue()});
2082  EXPECT_TRUE(contents.IsOpaque(matrix));
2083  contents.SetColors({Color::CornflowerBlue().WithAlpha(0.5)});
2084  EXPECT_FALSE(contents.IsOpaque(matrix));
2085  contents.SetColors({Color::CornflowerBlue()});
2086  contents.SetTileMode(Entity::TileMode::kDecal);
2087  EXPECT_FALSE(contents.IsOpaque(matrix));
2088 
2089  // Create stroked path that required alpha coverage.
2090  geom = Geometry::MakeStrokePath(
2091  PathBuilder{}.AddLine({0, 0}, {100, 100}).TakePath(),
2092  /*stroke_width=*/0.05);
2093  contents.SetGeometry(geom.get());
2094  contents.SetColors({Color::CornflowerBlue()});
2095 
2096  EXPECT_FALSE(contents.IsOpaque(matrix));
2097 }

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() [347/454]

impeller::testing::TEST_P ( EntityTest  ,
LinearToSrgbFilter   
)

Definition at line 1558 of file entity_unittests.cc.

1558  {
1559  auto image = CreateTextureForFixture("kalimba.jpg");
1560  ASSERT_TRUE(image);
1561 
1562  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
1563  auto filtered =
1564  ColorFilterContents::MakeLinearToSrgbFilter(FilterInput::Make(image));
1565 
1566  // Define the entity that will serve as the control image as a Gaussian blur
1567  // filter with no filter at all.
1568  Entity entity_left;
1569  entity_left.SetTransform(Matrix::MakeScale(GetContentScale()) *
1570  Matrix::MakeTranslation({100, 300}) *
1571  Matrix::MakeScale(Vector2{0.5, 0.5}));
1572  auto unfiltered = FilterContents::MakeGaussianBlur(FilterInput::Make(image),
1573  Sigma{0}, Sigma{0});
1574  entity_left.SetContents(unfiltered);
1575 
1576  // Define the entity that will be filtered from linear to sRGB.
1577  Entity entity_right;
1578  entity_right.SetTransform(Matrix::MakeScale(GetContentScale()) *
1579  Matrix::MakeTranslation({500, 300}) *
1580  Matrix::MakeScale(Vector2{0.5, 0.5}));
1581  entity_right.SetContents(filtered);
1582  return entity_left.Render(context, pass) &&
1583  entity_right.Render(context, pass);
1584  };
1585 
1586  ASSERT_TRUE(OpenPlaygroundHere(callback));
1587 }

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() [348/454]

impeller::testing::TEST_P ( EntityTest  ,
LinearToSrgbFilterCoverageIsCorrect   
)

Definition at line 1536 of file entity_unittests.cc.

1536  {
1537  // Set up a simple color background.
1538  auto geom = Geometry::MakeFillPath(
1539  PathBuilder{}.AddRect(Rect::MakeXYWH(0, 0, 300, 400)).TakePath());
1540  auto fill = std::make_shared<SolidColorContents>();
1541  fill->SetGeometry(geom.get());
1542  fill->SetColor(Color::MintCream());
1543 
1544  auto filter =
1545  ColorFilterContents::MakeLinearToSrgbFilter(FilterInput::Make(fill));
1546 
1547  Entity e;
1548  e.SetTransform(Matrix());
1549 
1550  // Confirm that the actual filter coverage matches the expected coverage.
1551  auto actual = filter->GetCoverage(e);
1552  auto expected = Rect::MakeXYWH(0, 0, 300, 400);
1553 
1554  ASSERT_TRUE(actual.has_value());
1555  ASSERT_RECT_NEAR(actual.value(), expected);
1556 }

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() [349/454]

impeller::testing::TEST_P ( EntityTest  ,
MorphologyFilter   
)

Definition at line 1080 of file entity_unittests.cc.

1080  {
1081  auto boston = CreateTextureForFixture("boston.jpg");
1082  ASSERT_TRUE(boston);
1083 
1084  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
1085  const char* morphology_type_names[] = {"Dilate", "Erode"};
1086  const FilterContents::MorphType morphology_types[] = {
1087  FilterContents::MorphType::kDilate, FilterContents::MorphType::kErode};
1088  static Color input_color = Color::Black();
1089  // UI state.
1090  static int selected_morphology_type = 0;
1091  static float radius[2] = {20, 20};
1092  static Color cover_color(1, 0, 0, 0.2);
1093  static Color bounds_color(0, 1, 0, 0.1);
1094  static float offset[2] = {500, 400};
1095  static float rotation = 0;
1096  static float scale[2] = {0.65, 0.65};
1097  static float skew[2] = {0, 0};
1098  static float path_rect[4] = {0, 0,
1099  static_cast<float>(boston->GetSize().width),
1100  static_cast<float>(boston->GetSize().height)};
1101  static float effect_transform_scale = 1;
1102 
1103  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
1104  {
1105  ImGui::Combo("Morphology type", &selected_morphology_type,
1106  morphology_type_names,
1107  sizeof(morphology_type_names) / sizeof(char*));
1108  ImGui::SliderFloat2("Radius", radius, 0, 200);
1109  ImGui::SliderFloat("Input opacity", &input_color.alpha, 0, 1);
1110  ImGui::ColorEdit4("Cover color", reinterpret_cast<float*>(&cover_color));
1111  ImGui::ColorEdit4("Bounds color ",
1112  reinterpret_cast<float*>(&bounds_color));
1113  ImGui::SliderFloat2("Translation", offset, 0,
1114  pass.GetRenderTargetSize().width);
1115  ImGui::SliderFloat("Rotation", &rotation, 0, kPi * 2);
1116  ImGui::SliderFloat2("Scale", scale, 0, 3);
1117  ImGui::SliderFloat2("Skew", skew, -3, 3);
1118  ImGui::SliderFloat4("Path XYWH", path_rect, -1000, 1000);
1119  ImGui::SliderFloat("Effect transform scale", &effect_transform_scale, 0,
1120  3);
1121  }
1122  ImGui::End();
1123 
1124  std::shared_ptr<Contents> input;
1125  Size input_size;
1126 
1127  auto input_rect =
1128  Rect::MakeXYWH(path_rect[0], path_rect[1], path_rect[2], path_rect[3]);
1129  auto texture = std::make_shared<TextureContents>();
1130  texture->SetSourceRect(Rect::MakeSize(boston->GetSize()));
1131  texture->SetDestinationRect(input_rect);
1132  texture->SetTexture(boston);
1133  texture->SetOpacity(input_color.alpha);
1134 
1135  input = texture;
1136  input_size = input_rect.GetSize();
1137 
1138  auto contents = FilterContents::MakeMorphology(
1139  FilterInput::Make(input), Radius{radius[0]}, Radius{radius[1]},
1140  morphology_types[selected_morphology_type]);
1141  contents->SetEffectTransform(Matrix::MakeScale(
1142  Vector2{effect_transform_scale, effect_transform_scale}));
1143 
1144  auto ctm = Matrix::MakeScale(GetContentScale()) *
1145  Matrix::MakeTranslation(Vector3(offset[0], offset[1])) *
1146  Matrix::MakeRotationZ(Radians(rotation)) *
1147  Matrix::MakeScale(Vector2(scale[0], scale[1])) *
1148  Matrix::MakeSkew(skew[0], skew[1]) *
1149  Matrix::MakeTranslation(-Point(input_size) / 2);
1150 
1151  Entity entity;
1152  entity.SetContents(contents);
1153  entity.SetTransform(ctm);
1154 
1155  entity.Render(context, pass);
1156 
1157  // Renders a red "cover" rectangle that shows the original position of the
1158  // unfiltered input.
1159  Entity cover_entity;
1160  static std::unique_ptr<Geometry> geom =
1161  Geometry::MakeFillPath(PathBuilder{}.AddRect(input_rect).TakePath());
1162  auto cover_contents = std::make_shared<SolidColorContents>();
1163  cover_contents->SetColor(cover_color);
1164  cover_contents->SetGeometry(geom.get());
1165  cover_entity.SetContents(cover_contents);
1166  cover_entity.SetTransform(ctm);
1167  cover_entity.Render(context, pass);
1168 
1169  // Renders a green bounding rect of the target filter.
1170  Entity bounds_entity;
1171  static std::unique_ptr<Geometry> bounds_geom = Geometry::MakeFillPath(
1172  PathBuilder{}
1173  .AddRect(contents->GetCoverage(entity).value())
1174  .TakePath());
1175  auto bounds_contents = std::make_shared<SolidColorContents>();
1176  bounds_contents->SetColor(bounds_color);
1177  bounds_contents->SetGeometry(bounds_geom.get());
1178  bounds_entity.SetContents(std::move(bounds_contents));
1179  bounds_entity.SetTransform(Matrix());
1180 
1181  bounds_entity.Render(context, pass);
1182 
1183  return true;
1184  };
1185  ASSERT_TRUE(OpenPlaygroundHere(callback));
1186 }

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() [350/454]

impeller::testing::TEST_P ( EntityTest  ,
PointFieldGeometryCoverage   
)

Definition at line 2158 of file entity_unittests.cc.

2158  {
2159  std::vector<Point> points = {{10, 20}, {100, 200}};
2160  auto geometry = Geometry::MakePointField(points, 5.0, false);
2161  ASSERT_EQ(*geometry->GetCoverage(Matrix()), Rect::MakeLTRB(5, 15, 105, 205));
2162  ASSERT_EQ(*geometry->GetCoverage(Matrix::MakeTranslation({30, 0, 0})),
2163  Rect::MakeLTRB(35, 15, 135, 205));
2164 }

References impeller::TRect< Scalar >::MakeLTRB(), impeller::Geometry::MakePointField(), and impeller::Matrix::MakeTranslation().

◆ TEST_P() [351/454]

impeller::testing::TEST_P ( EntityTest  ,
RadialGradientContentsIsOpaque   
)

Definition at line 2099 of file entity_unittests.cc.

2099  {
2100  Matrix matrix;
2101  RadialGradientContents contents;
2102  auto geom = Geometry::MakeRect(Rect::MakeLTRB(0, 0, 10, 10));
2103  contents.SetGeometry(geom.get());
2104 
2105  contents.SetColors({Color::CornflowerBlue()});
2106  EXPECT_TRUE(contents.IsOpaque(matrix));
2107  contents.SetColors({Color::CornflowerBlue().WithAlpha(0.5)});
2108  EXPECT_FALSE(contents.IsOpaque(matrix));
2109  contents.SetColors({Color::CornflowerBlue()});
2110  contents.SetTileMode(Entity::TileMode::kDecal);
2111  EXPECT_FALSE(contents.IsOpaque(matrix));
2112 
2113  // Create stroked path that required alpha coverage.
2114  geom = Geometry::MakeStrokePath(
2115  PathBuilder{}.AddLine({0, 0}, {100, 100}).TakePath(),
2116  /*stroke_width=*/0.05);
2117  contents.SetGeometry(geom.get());
2118  contents.SetColors({Color::CornflowerBlue()});
2119 
2120  EXPECT_FALSE(contents.IsOpaque(matrix));
2121 }

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() [352/454]

impeller::testing::TEST_P ( EntityTest  ,
RRectShadowTest   
)

Definition at line 1394 of file entity_unittests.cc.

1394  {
1395  auto callback = [&](ContentContext& context, RenderPass& pass) {
1396  static Color color = Color::Red();
1397  static float corner_radius = 100;
1398  static float blur_radius = 100;
1399  static bool show_coverage = false;
1400  static Color coverage_color = Color::Green().WithAlpha(0.2);
1401 
1402  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
1403  ImGui::SliderFloat("Corner radius", &corner_radius, 0, 300);
1404  ImGui::SliderFloat("Blur radius", &blur_radius, 0, 300);
1405  ImGui::ColorEdit4("Color", reinterpret_cast<Scalar*>(&color));
1406  ImGui::Checkbox("Show coverage", &show_coverage);
1407  if (show_coverage) {
1408  ImGui::ColorEdit4("Coverage color",
1409  reinterpret_cast<Scalar*>(&coverage_color));
1410  }
1411  ImGui::End();
1412 
1413  static PlaygroundPoint top_left_point(Point(200, 200), 30, Color::White());
1414  static PlaygroundPoint bottom_right_point(Point(600, 400), 30,
1415  Color::White());
1416  auto [top_left, bottom_right] =
1417  DrawPlaygroundLine(top_left_point, bottom_right_point);
1418  auto rect =
1419  Rect::MakeLTRB(top_left.x, top_left.y, bottom_right.x, bottom_right.y);
1420 
1421  auto contents = std::make_unique<SolidRRectBlurContents>();
1422  contents->SetRRect(rect, {corner_radius, corner_radius});
1423  contents->SetColor(color);
1424  contents->SetSigma(Radius(blur_radius));
1425 
1426  Entity entity;
1427  entity.SetTransform(Matrix::MakeScale(GetContentScale()));
1428  entity.SetContents(std::move(contents));
1429  entity.Render(context, pass);
1430 
1431  auto coverage = entity.GetCoverage();
1432  if (show_coverage && coverage.has_value()) {
1433  auto bounds_contents = std::make_unique<SolidColorContents>();
1434  auto geom = Geometry::MakeFillPath(
1435  PathBuilder{}.AddRect(entity.GetCoverage().value()).TakePath());
1436  bounds_contents->SetGeometry(geom.get());
1437  bounds_contents->SetColor(coverage_color.Premultiply());
1438  Entity bounds_entity;
1439  bounds_entity.SetContents(std::move(bounds_contents));
1440  bounds_entity.Render(context, pass);
1441  }
1442 
1443  return true;
1444  };
1445  ASSERT_TRUE(OpenPlaygroundHere(callback));
1446 }

References impeller::PathBuilder::AddRect(), blur_radius, color, impeller::DrawPlaygroundLine(), impeller::Entity::GetCoverage(), impeller::Color::Green(), impeller::Geometry::MakeFillPath(), impeller::TRect< Scalar >::MakeLTRB(), impeller::Matrix::MakeScale(), impeller::Color::Premultiply(), impeller::Color::Red(), impeller::Entity::Render(), impeller::Entity::SetContents(), impeller::Entity::SetTransform(), impeller::PathBuilder::TakePath(), impeller::Color::White(), and impeller::Color::WithAlpha().

◆ TEST_P() [353/454]

impeller::testing::TEST_P ( EntityTest  ,
RuntimeEffect   
)

Definition at line 1754 of file entity_unittests.cc.

1754  {
1755  auto runtime_stages =
1756  OpenAssetAsRuntimeStage("runtime_stage_example.frag.iplr");
1757  auto runtime_stage =
1758  runtime_stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
1759  ASSERT_TRUE(runtime_stage);
1760  ASSERT_TRUE(runtime_stage->IsDirty());
1761 
1762  bool expect_dirty = true;
1763  Pipeline<PipelineDescriptor>* first_pipeline;
1764  static std::unique_ptr<Geometry> geom = Geometry::MakeCover();
1765 
1766  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
1767  EXPECT_EQ(runtime_stage->IsDirty(), expect_dirty);
1768 
1769  auto contents = std::make_shared<RuntimeEffectContents>();
1770  contents->SetGeometry(geom.get());
1771  contents->SetRuntimeStage(runtime_stage);
1772 
1773  struct FragUniforms {
1774  Vector2 iResolution;
1775  Scalar iTime;
1776  } frag_uniforms = {
1777  .iResolution = Vector2(GetWindowSize().width, GetWindowSize().height),
1778  .iTime = static_cast<Scalar>(GetSecondsElapsed()),
1779  };
1780  auto uniform_data = std::make_shared<std::vector<uint8_t>>();
1781  uniform_data->resize(sizeof(FragUniforms));
1782  memcpy(uniform_data->data(), &frag_uniforms, sizeof(FragUniforms));
1783  contents->SetUniformData(uniform_data);
1784 
1785  Entity entity;
1786  entity.SetContents(contents);
1787  bool result = contents->Render(context, entity, pass);
1788 
1789  if (expect_dirty) {
1790  EXPECT_NE(first_pipeline, pass.GetCommands().back().pipeline.get());
1791  first_pipeline = pass.GetCommands().back().pipeline.get();
1792  } else {
1793  EXPECT_EQ(pass.GetCommands().back().pipeline.get(), first_pipeline);
1794  }
1795 
1796  expect_dirty = false;
1797  return result;
1798  };
1799 
1800  // Simulate some renders and hot reloading of the shader.
1801  auto content_context = GetContentContext();
1802  {
1803  RenderTarget target =
1804  content_context->GetRenderTargetCache()->CreateOffscreen(
1805  *content_context->GetContext(), {1, 1}, 1u);
1806 
1807  testing::MockRenderPass mock_pass(GetContext(), target);
1808  callback(*content_context, mock_pass);
1809  callback(*content_context, mock_pass);
1810 
1811  // Dirty the runtime stage.
1812  runtime_stages = OpenAssetAsRuntimeStage("runtime_stage_example.frag.iplr");
1813  runtime_stage =
1814  runtime_stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
1815 
1816  ASSERT_TRUE(runtime_stage->IsDirty());
1817  expect_dirty = true;
1818 
1819  callback(*content_context, mock_pass);
1820  }
1821 }

References impeller::Geometry::MakeCover(), impeller::PlaygroundBackendToRuntimeStageBackend(), and impeller::Entity::SetContents().

◆ TEST_P() [354/454]

impeller::testing::TEST_P ( EntityTest  ,
RuntimeEffectCanPrecache   
)

Definition at line 1870 of file entity_unittests.cc.

1870  {
1871  auto runtime_stages =
1872  OpenAssetAsRuntimeStage("runtime_stage_example.frag.iplr");
1873  auto runtime_stage =
1874  runtime_stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
1875  ASSERT_TRUE(runtime_stage);
1876  ASSERT_TRUE(runtime_stage->IsDirty());
1877 
1878  auto contents = std::make_shared<RuntimeEffectContents>();
1879  contents->SetRuntimeStage(runtime_stage);
1880 
1881  EXPECT_TRUE(contents->BootstrapShader(*GetContentContext()));
1882 }

References impeller::PlaygroundBackendToRuntimeStageBackend().

◆ TEST_P() [355/454]

impeller::testing::TEST_P ( EntityTest  ,
RuntimeEffectCanSuccessfullyRender   
)

Definition at line 1823 of file entity_unittests.cc.

1823  {
1824  auto runtime_stages =
1825  OpenAssetAsRuntimeStage("runtime_stage_example.frag.iplr");
1826  auto runtime_stage =
1827  runtime_stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
1828  ASSERT_TRUE(runtime_stage);
1829  ASSERT_TRUE(runtime_stage->IsDirty());
1830 
1831  auto contents = std::make_shared<RuntimeEffectContents>();
1832  auto geom = Geometry::MakeCover();
1833  contents->SetGeometry(geom.get());
1834  contents->SetRuntimeStage(runtime_stage);
1835 
1836  struct FragUniforms {
1837  Vector2 iResolution;
1838  Scalar iTime;
1839  } frag_uniforms = {
1840  .iResolution = Vector2(GetWindowSize().width, GetWindowSize().height),
1841  .iTime = static_cast<Scalar>(GetSecondsElapsed()),
1842  };
1843  auto uniform_data = std::make_shared<std::vector<uint8_t>>();
1844  uniform_data->resize(sizeof(FragUniforms));
1845  memcpy(uniform_data->data(), &frag_uniforms, sizeof(FragUniforms));
1846  contents->SetUniformData(uniform_data);
1847 
1848  Entity entity;
1849  entity.SetContents(contents);
1850 
1851  // Create a render target with a depth-stencil, similar to how EntityPass
1852  // does.
1853  RenderTarget target =
1854  GetContentContext()->GetRenderTargetCache()->CreateOffscreenMSAA(
1855  *GetContext(), {GetWindowSize().width, GetWindowSize().height}, 1,
1856  "RuntimeEffect Texture");
1857  testing::MockRenderPass pass(GetContext(), target);
1858 
1859  ASSERT_TRUE(contents->Render(*GetContentContext(), entity, pass));
1860  ASSERT_EQ(pass.GetCommands().size(), 1u);
1861  const auto& command = pass.GetCommands()[0];
1862  ASSERT_TRUE(command.pipeline->GetDescriptor()
1863  .GetDepthStencilAttachmentDescriptor()
1864  .has_value());
1865  ASSERT_TRUE(command.pipeline->GetDescriptor()
1866  .GetFrontStencilAttachmentDescriptor()
1867  .has_value());
1868 }

References impeller::Geometry::MakeCover(), impeller::PlaygroundBackendToRuntimeStageBackend(), and impeller::Entity::SetContents().

◆ TEST_P() [356/454]

impeller::testing::TEST_P ( EntityTest  ,
RuntimeEffectSetsRightSizeWhenUniformIsStruct   
)

Definition at line 1884 of file entity_unittests.cc.

1884  {
1885  if (GetBackend() != PlaygroundBackend::kVulkan) {
1886  GTEST_SKIP() << "Test only applies to Vulkan";
1887  }
1888 
1889  auto runtime_stages =
1890  OpenAssetAsRuntimeStage("runtime_stage_example.frag.iplr");
1891  auto runtime_stage =
1892  runtime_stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
1893  ASSERT_TRUE(runtime_stage);
1894  ASSERT_TRUE(runtime_stage->IsDirty());
1895 
1896  auto contents = std::make_shared<RuntimeEffectContents>();
1897  auto geom = Geometry::MakeCover();
1898  contents->SetGeometry(geom.get());
1899  contents->SetRuntimeStage(runtime_stage);
1900 
1901  struct FragUniforms {
1902  Vector2 iResolution;
1903  Scalar iTime;
1904  } frag_uniforms = {
1905  .iResolution = Vector2(GetWindowSize().width, GetWindowSize().height),
1906  .iTime = static_cast<Scalar>(GetSecondsElapsed()),
1907  };
1908  auto uniform_data = std::make_shared<std::vector<uint8_t>>();
1909  uniform_data->resize(sizeof(FragUniforms));
1910  memcpy(uniform_data->data(), &frag_uniforms, sizeof(FragUniforms));
1911  contents->SetUniformData(uniform_data);
1912 
1913  Entity entity;
1914  entity.SetContents(contents);
1915 
1916  auto context = GetContentContext();
1917  RenderTarget target = context->GetRenderTargetCache()->CreateOffscreen(
1918  *context->GetContext(), {1, 1}, 1u);
1919 
1920  testing::MockRenderPass pass(GetContext(), target);
1921  ASSERT_TRUE(contents->Render(*context, entity, pass));
1922  ASSERT_EQ(pass.GetCommands().size(), 1u);
1923  const auto& command = pass.GetCommands()[0];
1924  ASSERT_EQ(command.fragment_bindings.buffers.size(), 1u);
1925  // 16 bytes:
1926  // 8 bytes for iResolution
1927  // 4 bytes for iTime
1928  // 4 bytes padding
1929  EXPECT_EQ(command.fragment_bindings.buffers[0].view.resource.range.length,
1930  16u);
1931 }

References impeller::kVulkan, impeller::Geometry::MakeCover(), impeller::PlaygroundBackendToRuntimeStageBackend(), and impeller::Entity::SetContents().

◆ TEST_P() [357/454]

impeller::testing::TEST_P ( EntityTest  ,
SetBlendMode   
)

Definition at line 1188 of file entity_unittests.cc.

1188  {
1189  Entity entity;
1190  ASSERT_EQ(entity.GetBlendMode(), BlendMode::kSourceOver);
1191  entity.SetBlendMode(BlendMode::kClear);
1192  ASSERT_EQ(entity.GetBlendMode(), BlendMode::kClear);
1193 }

References impeller::Entity::GetBlendMode(), impeller::kClear, impeller::kSourceOver, and impeller::Entity::SetBlendMode().

◆ TEST_P() [358/454]

impeller::testing::TEST_P ( EntityTest  ,
SolidColorApplyColorFilter   
)

Definition at line 2399 of file entity_unittests.cc.

2399  {
2400  auto contents = SolidColorContents();
2401  contents.SetColor(Color::CornflowerBlue().WithAlpha(0.75));
2402  auto result = contents.ApplyColorFilter([](const Color& color) {
2403  return color.Blend(Color::LimeGreen().WithAlpha(0.75), BlendMode::kScreen);
2404  });
2405  ASSERT_TRUE(result);
2406  ASSERT_COLOR_NEAR(contents.GetColor(),
2407  Color(0.424452, 0.828743, 0.79105, 0.9375));
2408 }

References ASSERT_COLOR_NEAR, color, impeller::Color::CornflowerBlue(), impeller::kScreen, and impeller::Color::LimeGreen().

◆ TEST_P() [359/454]

impeller::testing::TEST_P ( EntityTest  ,
SolidColorContentsIsOpaque   
)

Definition at line 2033 of file entity_unittests.cc.

2033  {
2034  Matrix matrix;
2035  SolidColorContents contents;
2036  auto geom = Geometry::MakeRect(Rect::MakeLTRB(0, 0, 10, 10));
2037  contents.SetGeometry(geom.get());
2038 
2039  contents.SetColor(Color::CornflowerBlue());
2040  EXPECT_TRUE(contents.IsOpaque(matrix));
2041  contents.SetColor(Color::CornflowerBlue().WithAlpha(0.5));
2042  EXPECT_FALSE(contents.IsOpaque(matrix));
2043 
2044  // Create stroked path that required alpha coverage.
2045  geom = Geometry::MakeStrokePath(
2046  PathBuilder{}.AddLine({0, 0}, {100, 100}).TakePath(),
2047  /*stroke_width=*/0.05);
2048  contents.SetGeometry(geom.get());
2049  contents.SetColor(Color::CornflowerBlue());
2050 
2051  EXPECT_FALSE(contents.IsOpaque(matrix));
2052 }

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() [360/454]

impeller::testing::TEST_P ( EntityTest  ,
SolidColorContentsStrokeSetMiterLimit   
)

Definition at line 677 of file entity_unittests.cc.

677  {
678  {
679  auto geometry = Geometry::MakeStrokePath(Path{});
680  auto path_geometry = static_cast<StrokePathGeometry*>(geometry.get());
681  ASSERT_FLOAT_EQ(path_geometry->GetMiterLimit(), 4);
682  }
683 
684  {
685  auto geometry = Geometry::MakeStrokePath(Path{}, 1.0,
686  /*miter_limit=*/8.0);
687  auto path_geometry = static_cast<StrokePathGeometry*>(geometry.get());
688  ASSERT_FLOAT_EQ(path_geometry->GetMiterLimit(), 8);
689  }
690 
691  {
692  auto geometry = Geometry::MakeStrokePath(Path{}, 1.0,
693  /*miter_limit=*/-1.0);
694  auto path_geometry = static_cast<StrokePathGeometry*>(geometry.get());
695  ASSERT_FLOAT_EQ(path_geometry->GetMiterLimit(), 4);
696  }
697 }

References impeller::Geometry::MakeStrokePath().

◆ TEST_P() [361/454]

impeller::testing::TEST_P ( EntityTest  ,
SolidColorContentsStrokeSetStrokeCapsAndJoins   
)

Definition at line 655 of file entity_unittests.cc.

655  {
656  {
657  auto geometry = Geometry::MakeStrokePath(Path{});
658  auto path_geometry = static_cast<StrokePathGeometry*>(geometry.get());
659  // Defaults.
660  ASSERT_EQ(path_geometry->GetStrokeCap(), Cap::kButt);
661  ASSERT_EQ(path_geometry->GetStrokeJoin(), Join::kMiter);
662  }
663 
664  {
665  auto geometry = Geometry::MakeStrokePath(Path{}, 1.0, 4.0, Cap::kSquare);
666  auto path_geometry = static_cast<StrokePathGeometry*>(geometry.get());
667  ASSERT_EQ(path_geometry->GetStrokeCap(), Cap::kSquare);
668  }
669 
670  {
671  auto geometry = Geometry::MakeStrokePath(Path{}, 1.0, 4.0, Cap::kRound);
672  auto path_geometry = static_cast<StrokePathGeometry*>(geometry.get());
673  ASSERT_EQ(path_geometry->GetStrokeCap(), Cap::kRound);
674  }
675 }

References impeller::kButt, impeller::kMiter, impeller::kRound, impeller::kSquare, and impeller::Geometry::MakeStrokePath().

◆ TEST_P() [362/454]

impeller::testing::TEST_P ( EntityTest  ,
SolidFillCoverageIsCorrect   
)

Definition at line 1285 of file entity_unittests.cc.

1285  {
1286  // No transform
1287  {
1288  auto fill = std::make_shared<SolidColorContents>();
1289  fill->SetColor(Color::CornflowerBlue());
1290  auto expected = Rect::MakeLTRB(100, 110, 200, 220);
1291  auto geom =
1292  Geometry::MakeFillPath(PathBuilder{}.AddRect(expected).TakePath());
1293  fill->SetGeometry(geom.get());
1294 
1295  auto coverage = fill->GetCoverage({});
1296  ASSERT_TRUE(coverage.has_value());
1297  ASSERT_RECT_NEAR(coverage.value(), expected);
1298  }
1299 
1300  // Entity transform
1301  {
1302  auto fill = std::make_shared<SolidColorContents>();
1303  auto geom = Geometry::MakeFillPath(
1304  PathBuilder{}.AddRect(Rect::MakeLTRB(100, 110, 200, 220)).TakePath());
1305  fill->SetColor(Color::CornflowerBlue());
1306  fill->SetGeometry(geom.get());
1307 
1308  Entity entity;
1309  entity.SetTransform(Matrix::MakeTranslation(Vector2(4, 5)));
1310  entity.SetContents(std::move(fill));
1311 
1312  auto coverage = entity.GetCoverage();
1313  auto expected = Rect::MakeLTRB(104, 115, 204, 225);
1314  ASSERT_TRUE(coverage.has_value());
1315  ASSERT_RECT_NEAR(coverage.value(), expected);
1316  }
1317 
1318  // No coverage for fully transparent colors
1319  {
1320  auto fill = std::make_shared<SolidColorContents>();
1321  auto geom = Geometry::MakeFillPath(
1322  PathBuilder{}.AddRect(Rect::MakeLTRB(100, 110, 200, 220)).TakePath());
1323  fill->SetColor(Color::WhiteTransparent());
1324  fill->SetGeometry(geom.get());
1325 
1326  auto coverage = fill->GetCoverage({});
1327  ASSERT_FALSE(coverage.has_value());
1328  }
1329 }

References impeller::PathBuilder::AddRect(), ASSERT_RECT_NEAR, impeller::Color::CornflowerBlue(), impeller::Entity::GetCoverage(), impeller::Geometry::MakeFillPath(), impeller::TRect< Scalar >::MakeLTRB(), impeller::Matrix::MakeTranslation(), impeller::Entity::SetContents(), impeller::Entity::SetTransform(), and impeller::Color::WhiteTransparent().

◆ TEST_P() [363/454]

impeller::testing::TEST_P ( EntityTest  ,
SolidStrokeCoverageIsCorrect   
)

Definition at line 1201 of file entity_unittests.cc.

1201  {
1202  {
1203  auto geometry = Geometry::MakeStrokePath(
1204  PathBuilder{}.AddLine({0, 0}, {10, 10}).TakePath(), 4.0, 4.0,
1205  Cap::kButt, Join::kBevel);
1206 
1207  Entity entity;
1208  auto contents = std::make_unique<SolidColorContents>();
1209  contents->SetGeometry(geometry.get());
1210  contents->SetColor(Color::Black());
1211  entity.SetContents(std::move(contents));
1212  auto actual = entity.GetCoverage();
1213  auto expected = Rect::MakeLTRB(-2, -2, 12, 12);
1214 
1215  ASSERT_TRUE(actual.has_value());
1216  ASSERT_RECT_NEAR(actual.value(), expected);
1217  }
1218 
1219  // Cover the Cap::kSquare case.
1220  {
1221  auto geometry = Geometry::MakeStrokePath(
1222  PathBuilder{}.AddLine({0, 0}, {10, 10}).TakePath(), 4.0, 4.0,
1223  Cap::kSquare, Join::kBevel);
1224 
1225  Entity entity;
1226  auto contents = std::make_unique<SolidColorContents>();
1227  contents->SetGeometry(geometry.get());
1228  contents->SetColor(Color::Black());
1229  entity.SetContents(std::move(contents));
1230  auto actual = entity.GetCoverage();
1231  auto expected =
1232  Rect::MakeLTRB(-sqrt(8), -sqrt(8), 10 + sqrt(8), 10 + sqrt(8));
1233 
1234  ASSERT_TRUE(actual.has_value());
1235  ASSERT_RECT_NEAR(actual.value(), expected);
1236  }
1237 
1238  // Cover the Join::kMiter case.
1239  {
1240  auto geometry = Geometry::MakeStrokePath(
1241  PathBuilder{}.AddLine({0, 0}, {10, 10}).TakePath(), 4.0, 2.0,
1242  Cap::kSquare, Join::kMiter);
1243 
1244  Entity entity;
1245  auto contents = std::make_unique<SolidColorContents>();
1246  contents->SetGeometry(geometry.get());
1247  contents->SetColor(Color::Black());
1248  entity.SetContents(std::move(contents));
1249  auto actual = entity.GetCoverage();
1250  auto expected = Rect::MakeLTRB(-4, -4, 14, 14);
1251 
1252  ASSERT_TRUE(actual.has_value());
1253  ASSERT_RECT_NEAR(actual.value(), expected);
1254  }
1255 }

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() [364/454]

impeller::testing::TEST_P ( EntityTest  ,
SpecializationConstantsAreAppliedToVariants   
)

Definition at line 2194 of file entity_unittests.cc.

2194  {
2195  auto content_context = GetContentContext();
2196 
2197  auto default_gyph = content_context->GetGlyphAtlasPipeline({
2198  .color_attachment_pixel_format = PixelFormat::kR8G8B8A8UNormInt,
2199  .has_depth_stencil_attachments = false,
2200  });
2201  auto alt_gyph = content_context->GetGlyphAtlasPipeline(
2202  {.color_attachment_pixel_format = PixelFormat::kR8G8B8A8UNormInt,
2203  .has_depth_stencil_attachments = true});
2204 
2205  EXPECT_NE(default_gyph, alt_gyph);
2206  EXPECT_EQ(default_gyph->GetDescriptor().GetSpecializationConstants(),
2207  alt_gyph->GetDescriptor().GetSpecializationConstants());
2208 
2209  auto use_a8 = GetContext()->GetCapabilities()->GetDefaultGlyphAtlasFormat() ==
2210  PixelFormat::kA8UNormInt;
2211 
2212  std::vector<Scalar> expected_constants = {static_cast<Scalar>(use_a8)};
2213  EXPECT_EQ(default_gyph->GetDescriptor().GetSpecializationConstants(),
2214  expected_constants);
2215 }

References impeller::kA8UNormInt, and impeller::kR8G8B8A8UNormInt.

◆ TEST_P() [365/454]

impeller::testing::TEST_P ( EntityTest  ,
SrgbToLinearFilter   
)

Definition at line 1611 of file entity_unittests.cc.

1611  {
1612  auto image = CreateTextureForFixture("embarcadero.jpg");
1613  ASSERT_TRUE(image);
1614 
1615  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
1616  auto filtered =
1617  ColorFilterContents::MakeSrgbToLinearFilter(FilterInput::Make(image));
1618 
1619  // Define the entity that will serve as the control image as a Gaussian blur
1620  // filter with no filter at all.
1621  Entity entity_left;
1622  entity_left.SetTransform(Matrix::MakeScale(GetContentScale()) *
1623  Matrix::MakeTranslation({100, 300}) *
1624  Matrix::MakeScale(Vector2{0.5, 0.5}));
1625  auto unfiltered = FilterContents::MakeGaussianBlur(FilterInput::Make(image),
1626  Sigma{0}, Sigma{0});
1627  entity_left.SetContents(unfiltered);
1628 
1629  // Define the entity that will be filtered from sRGB to linear.
1630  Entity entity_right;
1631  entity_right.SetTransform(Matrix::MakeScale(GetContentScale()) *
1632  Matrix::MakeTranslation({500, 300}) *
1633  Matrix::MakeScale(Vector2{0.5, 0.5}));
1634  entity_right.SetContents(filtered);
1635  return entity_left.Render(context, pass) &&
1636  entity_right.Render(context, pass);
1637  };
1638 
1639  ASSERT_TRUE(OpenPlaygroundHere(callback));
1640 }

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() [366/454]

impeller::testing::TEST_P ( EntityTest  ,
SrgbToLinearFilterCoverageIsCorrect   
)

Definition at line 1589 of file entity_unittests.cc.

1589  {
1590  // Set up a simple color background.
1591  auto fill = std::make_shared<SolidColorContents>();
1592  auto geom = Geometry::MakeFillPath(
1593  PathBuilder{}.AddRect(Rect::MakeXYWH(0, 0, 300, 400)).TakePath());
1594  fill->SetGeometry(geom.get());
1595  fill->SetColor(Color::DeepPink());
1596 
1597  auto filter =
1598  ColorFilterContents::MakeSrgbToLinearFilter(FilterInput::Make(fill));
1599 
1600  Entity e;
1601  e.SetTransform(Matrix());
1602 
1603  // Confirm that the actual filter coverage matches the expected coverage.
1604  auto actual = filter->GetCoverage(e);
1605  auto expected = Rect::MakeXYWH(0, 0, 300, 400);
1606 
1607  ASSERT_TRUE(actual.has_value());
1608  ASSERT_RECT_NEAR(actual.value(), expected);
1609 }

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() [367/454]

impeller::testing::TEST_P ( EntityTest  ,
StrokeCapAndJoinTest   
)

Definition at line 194 of file entity_unittests.cc.

194  {
195  const Point padding(300, 250);
196  const Point margin(140, 180);
197 
198  auto callback = [&](ContentContext& context, RenderPass& pass) {
199  // Slightly above sqrt(2) by default, so that right angles are just below
200  // the limit and acute angles are over the limit (causing them to get
201  // beveled).
202  static Scalar miter_limit = 1.41421357;
203  static Scalar width = 30;
204 
205  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
206  {
207  ImGui::SliderFloat("Miter limit", &miter_limit, 0, 30);
208  ImGui::SliderFloat("Stroke width", &width, 0, 100);
209  if (ImGui::Button("Reset")) {
210  miter_limit = 1.41421357;
211  width = 30;
212  }
213  }
214  ImGui::End();
215 
216  auto world_matrix = Matrix::MakeScale(GetContentScale());
217  auto render_path = [width = width, &context, &pass, &world_matrix](
218  const Path& path, Cap cap, Join join) {
219  auto contents = std::make_unique<SolidColorContents>();
220  static std::unique_ptr<Geometry> geom =
221  Geometry::MakeStrokePath(path, width, miter_limit, cap, join);
222  contents->SetGeometry(geom.get());
223  contents->SetColor(Color::Red());
224 
225  Entity entity;
226  entity.SetTransform(world_matrix);
227  entity.SetContents(std::move(contents));
228 
229  auto coverage = entity.GetCoverage();
230  if (coverage.has_value()) {
231  auto bounds_contents = std::make_unique<SolidColorContents>();
232 
233  static std::unique_ptr<Geometry> geom = Geometry::MakeFillPath(
234  PathBuilder{}.AddRect(entity.GetCoverage().value()).TakePath());
235 
236  bounds_contents->SetGeometry(geom.get());
237  bounds_contents->SetColor(Color::Green().WithAlpha(0.5));
238  Entity bounds_entity;
239  bounds_entity.SetContents(std::move(bounds_contents));
240  bounds_entity.Render(context, pass);
241  }
242 
243  entity.Render(context, pass);
244  };
245 
246  const Point a_def(0, 0), b_def(0, 100), c_def(150, 0), d_def(150, -100),
247  e_def(75, 75);
248  const Scalar r = 30;
249  // Cap::kButt demo.
250  {
251  Point off = Point(0, 0) * padding + margin;
252  static PlaygroundPoint point_a(off + a_def, r, Color::Black());
253  static PlaygroundPoint point_b(off + b_def, r, Color::White());
254  auto [a, b] = DrawPlaygroundLine(point_a, point_b);
255  static PlaygroundPoint point_c(off + c_def, r, Color::Black());
256  static PlaygroundPoint point_d(off + d_def, r, Color::White());
257  auto [c, d] = DrawPlaygroundLine(point_c, point_d);
258  render_path(PathBuilder{}.AddCubicCurve(a, b, d, c).TakePath(),
259  Cap::kButt, Join::kBevel);
260  }
261 
262  // Cap::kSquare demo.
263  {
264  Point off = Point(1, 0) * padding + margin;
265  static PlaygroundPoint point_a(off + a_def, r, Color::Black());
266  static PlaygroundPoint point_b(off + b_def, r, Color::White());
267  auto [a, b] = DrawPlaygroundLine(point_a, point_b);
268  static PlaygroundPoint point_c(off + c_def, r, Color::Black());
269  static PlaygroundPoint point_d(off + d_def, r, Color::White());
270  auto [c, d] = DrawPlaygroundLine(point_c, point_d);
271  render_path(PathBuilder{}.AddCubicCurve(a, b, d, c).TakePath(),
272  Cap::kSquare, Join::kBevel);
273  }
274 
275  // Cap::kRound demo.
276  {
277  Point off = Point(2, 0) * padding + margin;
278  static PlaygroundPoint point_a(off + a_def, r, Color::Black());
279  static PlaygroundPoint point_b(off + b_def, r, Color::White());
280  auto [a, b] = DrawPlaygroundLine(point_a, point_b);
281  static PlaygroundPoint point_c(off + c_def, r, Color::Black());
282  static PlaygroundPoint point_d(off + d_def, r, Color::White());
283  auto [c, d] = DrawPlaygroundLine(point_c, point_d);
284  render_path(PathBuilder{}.AddCubicCurve(a, b, d, c).TakePath(),
285  Cap::kRound, Join::kBevel);
286  }
287 
288  // Join::kBevel demo.
289  {
290  Point off = Point(0, 1) * padding + margin;
291  static PlaygroundPoint point_a =
292  PlaygroundPoint(off + a_def, r, Color::White());
293  static PlaygroundPoint point_b =
294  PlaygroundPoint(off + e_def, r, Color::White());
295  static PlaygroundPoint point_c =
296  PlaygroundPoint(off + c_def, r, Color::White());
297  Point a = DrawPlaygroundPoint(point_a);
298  Point b = DrawPlaygroundPoint(point_b);
299  Point c = DrawPlaygroundPoint(point_c);
300  render_path(
301  PathBuilder{}.MoveTo(a).LineTo(b).LineTo(c).Close().TakePath(),
302  Cap::kButt, Join::kBevel);
303  }
304 
305  // Join::kMiter demo.
306  {
307  Point off = Point(1, 1) * padding + margin;
308  static PlaygroundPoint point_a(off + a_def, r, Color::White());
309  static PlaygroundPoint point_b(off + e_def, r, Color::White());
310  static PlaygroundPoint point_c(off + c_def, r, Color::White());
311  Point a = DrawPlaygroundPoint(point_a);
312  Point b = DrawPlaygroundPoint(point_b);
313  Point c = DrawPlaygroundPoint(point_c);
314  render_path(
315  PathBuilder{}.MoveTo(a).LineTo(b).LineTo(c).Close().TakePath(),
316  Cap::kButt, Join::kMiter);
317  }
318 
319  // Join::kRound demo.
320  {
321  Point off = Point(2, 1) * padding + margin;
322  static PlaygroundPoint point_a(off + a_def, r, Color::White());
323  static PlaygroundPoint point_b(off + e_def, r, Color::White());
324  static PlaygroundPoint point_c(off + c_def, r, Color::White());
325  Point a = DrawPlaygroundPoint(point_a);
326  Point b = DrawPlaygroundPoint(point_b);
327  Point c = DrawPlaygroundPoint(point_c);
328  render_path(
329  PathBuilder{}.MoveTo(a).LineTo(b).LineTo(c).Close().TakePath(),
330  Cap::kButt, Join::kRound);
331  }
332 
333  return true;
334  };
335  ASSERT_TRUE(OpenPlaygroundHere(callback));
336 }

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() [368/454]

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  static 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() [369/454]

impeller::testing::TEST_P ( EntityTest  ,
SweepGradientContentsIsOpaque   
)

Definition at line 2123 of file entity_unittests.cc.

2123  {
2124  Matrix matrix;
2125  RadialGradientContents contents;
2126  auto geom = Geometry::MakeRect(Rect::MakeLTRB(0, 0, 10, 10));
2127  contents.SetGeometry(geom.get());
2128 
2129  contents.SetColors({Color::CornflowerBlue()});
2130  EXPECT_TRUE(contents.IsOpaque(matrix));
2131  contents.SetColors({Color::CornflowerBlue().WithAlpha(0.5)});
2132  EXPECT_FALSE(contents.IsOpaque(matrix));
2133  contents.SetColors({Color::CornflowerBlue()});
2134  contents.SetTileMode(Entity::TileMode::kDecal);
2135  EXPECT_FALSE(contents.IsOpaque(matrix));
2136 
2137  // Create stroked path that required alpha coverage.
2138  geom = Geometry::MakeStrokePath(
2139  PathBuilder{}.AddLine({0, 0}, {100, 100}).TakePath(),
2140  /*stroke_width=*/0.05);
2141  contents.SetGeometry(geom.get());
2142  contents.SetColors({Color::CornflowerBlue()});
2143 
2144  EXPECT_FALSE(contents.IsOpaque(matrix));
2145 }

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() [370/454]

impeller::testing::TEST_P ( EntityTest  ,
TextContentsCeilsGlyphScaleToDecimal   
)

Definition at line 2186 of file entity_unittests.cc.

2186  {
2187  ASSERT_EQ(TextFrame::RoundScaledFontSize(0.4321111f, 12), 0.43f);
2188  ASSERT_EQ(TextFrame::RoundScaledFontSize(0.5321111f, 12), 0.53f);
2189  ASSERT_EQ(TextFrame::RoundScaledFontSize(2.1f, 12), 2.1f);
2190  ASSERT_EQ(TextFrame::RoundScaledFontSize(0.0f, 12), 0.0f);
2191  ASSERT_EQ(TextFrame::RoundScaledFontSize(100000000.0f, 12), 48.0f);
2192 }

References impeller::TextFrame::RoundScaledFontSize().

◆ TEST_P() [371/454]

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  static 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() [372/454]

impeller::testing::TEST_P ( EntityTest  ,
TiledTextureContentsIsOpaque   
)

Definition at line 2147 of file entity_unittests.cc.

2147  {
2148  Matrix matrix;
2149  auto bay_bridge = CreateTextureForFixture("bay_bridge.jpg");
2150  TiledTextureContents contents;
2151  contents.SetTexture(bay_bridge);
2152  // This is a placeholder test. Images currently never decompress as opaque
2153  // (whether in Flutter or the playground), and so this should currently always
2154  // return false in practice.
2155  EXPECT_FALSE(contents.IsOpaque(matrix));
2156 }

References impeller::TiledTextureContents::IsOpaque(), and impeller::TiledTextureContents::SetTexture().

◆ TEST_P() [373/454]

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 }

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() [374/454]

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() [375/454]

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  static PlaygroundPoint point_a(Point(10, 10) + offset, 20, Color::White());
154  Point a = DrawPlaygroundPoint(point_a);
155  static PlaygroundPoint point_b(Point(210, 10) + offset, 20, Color::White());
156  Point b = DrawPlaygroundPoint(point_b);
157  static PlaygroundPoint point_c(Point(210, 210) + offset, 20,
158  Color::White());
159  Point c = DrawPlaygroundPoint(point_c);
160  static PlaygroundPoint point_d(Point(10, 210) + offset, 20, Color::White());
161  Point d = DrawPlaygroundPoint(point_d);
162  static PlaygroundPoint point_e(Point(50, 50) + offset, 20, Color::White());
163  Point e = DrawPlaygroundPoint(point_e);
164  static PlaygroundPoint point_f(Point(100, 50) + offset, 20, Color::White());
165  Point f = DrawPlaygroundPoint(point_f);
166  static PlaygroundPoint point_g(Point(50, 150) + offset, 20, Color::White());
167  Point g = DrawPlaygroundPoint(point_g);
168  Path path = PathBuilder{}
169  .MoveTo(a)
170  .LineTo(b)
171  .LineTo(c)
172  .LineTo(d)
173  .Close()
174  .MoveTo(e)
175  .LineTo(f)
176  .LineTo(g)
177  .Close()
178  .TakePath();
179 
180  Entity entity;
181  entity.SetTransform(Matrix::MakeScale(GetContentScale()));
182  auto contents = std::make_unique<SolidColorContents>();
183  static std::unique_ptr<Geometry> geom =
184  Geometry::MakeStrokePath(path, 20.0);
185  contents->SetGeometry(geom.get());
186  contents->SetColor(Color::Red());
187  entity.SetContents(std::move(contents));
188 
189  return entity.Render(context, pass);
190  };
191  ASSERT_TRUE(OpenPlaygroundHere(callback));
192 }

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() [376/454]

impeller::testing::TEST_P ( EntityTest  ,
YUVToRGBFilter   
)

Definition at line 1720 of file entity_unittests.cc.

1720  {
1721  if (GetParam() == PlaygroundBackend::kOpenGLES) {
1722  // TODO(114588) : Support YUV to RGB filter on OpenGLES backend.
1723  GTEST_SKIP()
1724  << "YUV to RGB filter is not supported on OpenGLES backend yet.";
1725  }
1726 
1727  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
1728  YUVColorSpace yuv_color_space_array[2]{YUVColorSpace::kBT601FullRange,
1729  YUVColorSpace::kBT601LimitedRange};
1730  for (int i = 0; i < 2; i++) {
1731  auto yuv_color_space = yuv_color_space_array[i];
1732  auto textures =
1733  CreateTestYUVTextures(GetContext().get(), yuv_color_space);
1734  auto filter_contents = FilterContents::MakeYUVToRGBFilter(
1735  textures[0], textures[1], yuv_color_space);
1736  Entity filter_entity;
1737  filter_entity.SetContents(filter_contents);
1738  auto snapshot = filter_contents->RenderToSnapshot(context, filter_entity);
1739 
1740  Entity entity;
1741  auto contents = TextureContents::MakeRect(Rect::MakeLTRB(0, 0, 256, 256));
1742  contents->SetTexture(snapshot->texture);
1743  contents->SetSourceRect(Rect::MakeSize(snapshot->texture->GetSize()));
1744  entity.SetContents(contents);
1745  entity.SetTransform(
1746  Matrix::MakeTranslation({static_cast<Scalar>(100 + 400 * i), 300}));
1747  entity.Render(context, pass);
1748  }
1749  return true;
1750  };
1751  ASSERT_TRUE(OpenPlaygroundHere(callback));
1752 }

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() [377/454]

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() [378/454]

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() [379/454]

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() [380/454]

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() [381/454]

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() [382/454]

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() [383/454]

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() [384/454]

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() [385/454]

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() [386/454]

impeller::testing::TEST_P ( HostBufferTest  ,
CanEmplace   
)

Definition at line 19 of file host_buffer_unittests.cc.

19  {
20  struct Length2 {
21  uint8_t pad[2];
22  };
23  static_assert(sizeof(Length2) == 2u);
24 
25  auto buffer = HostBuffer::Create(GetContext()->GetResourceAllocator());
26 
27  for (size_t i = 0; i < 12500; i++) {
28  auto view = buffer->Emplace(Length2{});
29  ASSERT_TRUE(view);
30  ASSERT_EQ(view.range, Range(i * sizeof(Length2), 2u));
31  }
32 }

References impeller::HostBuffer::Create().

◆ TEST_P() [387/454]

impeller::testing::TEST_P ( HostBufferTest  ,
CanEmplaceWithAlignment   
)

Definition at line 34 of file host_buffer_unittests.cc.

34  {
35  struct Length2 {
36  uint8_t pad[2];
37  };
38  static_assert(sizeof(Length2) == 2);
39  struct alignas(16) Align16 {
40  uint8_t pad[2];
41  };
42  static_assert(alignof(Align16) == 16);
43  static_assert(sizeof(Align16) == 16);
44 
45  auto buffer = HostBuffer::Create(GetContext()->GetResourceAllocator());
46  ASSERT_TRUE(buffer);
47 
48  {
49  auto view = buffer->Emplace(Length2{});
50  ASSERT_TRUE(view);
51  ASSERT_EQ(view.range, Range(0u, 2u));
52  }
53 
54  {
55  auto view = buffer->Emplace(Align16{});
56  ASSERT_TRUE(view);
57  ASSERT_EQ(view.range.offset, 16u);
58  ASSERT_EQ(view.range.length, 16u);
59  }
60  {
61  auto view = buffer->Emplace(Length2{});
62  ASSERT_TRUE(view);
63  ASSERT_EQ(view.range, Range(32u, 2u));
64  }
65 
66  {
67  auto view = buffer->Emplace(Align16{});
68  ASSERT_TRUE(view);
69  ASSERT_EQ(view.range.offset, 48u);
70  ASSERT_EQ(view.range.length, 16u);
71  }
72 }

References impeller::HostBuffer::Create().

◆ TEST_P() [388/454]

impeller::testing::TEST_P ( HostBufferTest  ,
EmplaceWithFailingAllocationDoesntCrash   
)

Definition at line 196 of file host_buffer_unittests.cc.

196  {
197  ScopedValidationDisable disable;
198  std::shared_ptr<FailingAllocator> allocator =
199  std::make_shared<FailingAllocator>(GetContext()->GetResourceAllocator());
200  auto buffer = HostBuffer::Create(allocator);
201 
202  auto view = buffer->Emplace(nullptr, kMagicFailingAllocation, 0);
203 
204  EXPECT_EQ(view.buffer, nullptr);
205  EXPECT_EQ(view.range.offset, 0u);
206  EXPECT_EQ(view.range.length, 0u);
207 }

References impeller::HostBuffer::Create(), and kMagicFailingAllocation.

◆ TEST_P() [389/454]

impeller::testing::TEST_P ( HostBufferTest  ,
EmplaceWithProcIsAligned   
)

Definition at line 156 of file host_buffer_unittests.cc.

156  {
157  auto buffer = HostBuffer::Create(GetContext()->GetResourceAllocator());
158 
159  BufferView view = buffer->Emplace(std::array<char, 21>());
160  EXPECT_EQ(view.range, Range(0, 21));
161 
162  view = buffer->Emplace(64, 16, [](uint8_t*) {});
163  EXPECT_EQ(view.range, Range(32, 64));
164 }

References impeller::HostBuffer::Create(), and impeller::BufferView::range.

◆ TEST_P() [390/454]

impeller::testing::TEST_P ( HostBufferTest  ,
EmplacingLargerThanBlockSizeCreatesOneOffBuffer   
)

Definition at line 113 of file host_buffer_unittests.cc.

113  {
114  auto buffer = HostBuffer::Create(GetContext()->GetResourceAllocator());
115 
116  // Emplace an amount larger than the block size, to verify that the host
117  // buffer does not create a buffer.
118  auto buffer_view = buffer->Emplace(nullptr, 1024000 + 10, 0);
119 
120  EXPECT_EQ(buffer->GetStateForTest().current_buffer, 0u);
121  EXPECT_EQ(buffer->GetStateForTest().current_frame, 0u);
122  EXPECT_EQ(buffer->GetStateForTest().total_buffer_count, 1u);
123 }

References buffer_view, and impeller::HostBuffer::Create().

◆ TEST_P() [391/454]

impeller::testing::TEST_P ( HostBufferTest  ,
EmplacingLargerThanBlockSizeCreatesOneOffBufferCallback   
)

Definition at line 100 of file host_buffer_unittests.cc.

101  {
102  auto buffer = HostBuffer::Create(GetContext()->GetResourceAllocator());
103 
104  // Emplace an amount larger than the block size, to verify that the host
105  // buffer does not create a buffer.
106  auto buffer_view = buffer->Emplace(1024000 + 10, 0, [](uint8_t* data) {});
107 
108  EXPECT_EQ(buffer->GetStateForTest().current_buffer, 0u);
109  EXPECT_EQ(buffer->GetStateForTest().current_frame, 0u);
110  EXPECT_EQ(buffer->GetStateForTest().total_buffer_count, 1u);
111 }

References buffer_view, impeller::HostBuffer::Create(), and data.

◆ TEST_P() [392/454]

impeller::testing::TEST_P ( HostBufferTest  ,
HostBufferInitialState   
)

Definition at line 74 of file host_buffer_unittests.cc.

74  {
75  auto buffer = HostBuffer::Create(GetContext()->GetResourceAllocator());
76 
77  EXPECT_EQ(buffer->GetStateForTest().current_buffer, 0u);
78  EXPECT_EQ(buffer->GetStateForTest().current_frame, 0u);
79  EXPECT_EQ(buffer->GetStateForTest().total_buffer_count, 1u);
80 }

References impeller::HostBuffer::Create().

◆ TEST_P() [393/454]

impeller::testing::TEST_P ( HostBufferTest  ,
ResetIncrementsFrameCounter   
)

Definition at line 82 of file host_buffer_unittests.cc.

82  {
83  auto buffer = HostBuffer::Create(GetContext()->GetResourceAllocator());
84 
85  EXPECT_EQ(buffer->GetStateForTest().current_frame, 0u);
86 
87  buffer->Reset();
88  EXPECT_EQ(buffer->GetStateForTest().current_frame, 1u);
89 
90  buffer->Reset();
91  EXPECT_EQ(buffer->GetStateForTest().current_frame, 2u);
92 
93  buffer->Reset();
94  EXPECT_EQ(buffer->GetStateForTest().current_frame, 3u);
95 
96  buffer->Reset();
97  EXPECT_EQ(buffer->GetStateForTest().current_frame, 0u);
98 }

References impeller::HostBuffer::Create().

◆ TEST_P() [394/454]

impeller::testing::TEST_P ( HostBufferTest  ,
UnusedBuffersAreDiscardedWhenResetting   
)

Definition at line 125 of file host_buffer_unittests.cc.

125  {
126  auto buffer = HostBuffer::Create(GetContext()->GetResourceAllocator());
127 
128  // Emplace two large allocations to force the allocation of a second buffer.
129  auto buffer_view_a = buffer->Emplace(1020000, 0, [](uint8_t* data) {});
130  auto buffer_view_b = buffer->Emplace(1020000, 0, [](uint8_t* data) {});
131 
132  EXPECT_EQ(buffer->GetStateForTest().current_buffer, 1u);
133  EXPECT_EQ(buffer->GetStateForTest().total_buffer_count, 2u);
134  EXPECT_EQ(buffer->GetStateForTest().current_frame, 0u);
135 
136  // Reset until we get back to this frame.
137  for (auto i = 0; i < 4; i++) {
138  buffer->Reset();
139  }
140 
141  EXPECT_EQ(buffer->GetStateForTest().current_buffer, 0u);
142  EXPECT_EQ(buffer->GetStateForTest().total_buffer_count, 2u);
143  EXPECT_EQ(buffer->GetStateForTest().current_frame, 0u);
144 
145  // Now when we reset, the buffer should get dropped.
146  // Reset until we get back to this frame.
147  for (auto i = 0; i < 4; i++) {
148  buffer->Reset();
149  }
150 
151  EXPECT_EQ(buffer->GetStateForTest().current_buffer, 0u);
152  EXPECT_EQ(buffer->GetStateForTest().total_buffer_count, 1u);
153  EXPECT_EQ(buffer->GetStateForTest().current_frame, 0u);
154 }

References impeller::HostBuffer::Create(), and data.

◆ TEST_P() [395/454]

impeller::testing::TEST_P ( MatrixFilterContentsTest  ,
RenderCoverageMatchesGetCoverageClippedSubpassScale   
)

Definition at line 180 of file matrix_filter_contents_unittests.cc.

181  {
182  std::shared_ptr<Texture> texture = MakeTexture(ISize(100, 100));
183  MatrixFilterContents contents;
184  contents.SetInputs({FilterInput::Make(texture)});
185  contents.SetMatrix(Matrix::MakeScale({3, 3, 1}));
186  contents.SetEffectTransform(Matrix::MakeScale({2, 2, 1}));
187  contents.SetRenderingMode(
188  Entity::RenderingMode::kSubpassAppendSnapshotTransform);
189 
190  Entity entity;
191  entity.SetTransform(Matrix::MakeTranslation({100, 200, 0}));
192 
193  std::shared_ptr<ContentContext> renderer = GetContentContext();
194  std::optional<Entity> result =
195  contents.GetEntity(*renderer, entity, /*coverage_hint=*/{});
196  expectRenderCoverageEqual(result, contents.GetCoverage(entity),
197  Rect::MakeXYWH(100, 200, 300, 300));
198 }

References impeller::FilterContents::GetCoverage(), impeller::FilterContents::GetEntity(), impeller::Entity::kSubpassAppendSnapshotTransform, impeller::FilterInput::Make(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeTranslation(), impeller::TRect< Scalar >::MakeXYWH(), impeller::FilterContents::SetEffectTransform(), impeller::FilterContents::SetInputs(), impeller::MatrixFilterContents::SetMatrix(), impeller::MatrixFilterContents::SetRenderingMode(), and impeller::Entity::SetTransform().

◆ TEST_P() [396/454]

impeller::testing::TEST_P ( MatrixFilterContentsTest  ,
RenderCoverageMatchesGetCoverageClippedSubpassTranslate   
)

Definition at line 143 of file matrix_filter_contents_unittests.cc.

144  {
145  std::shared_ptr<Texture> texture = MakeTexture(ISize(100, 100));
146  MatrixFilterContents contents;
147  contents.SetInputs({FilterInput::Make(texture)});
148  contents.SetMatrix(Matrix::MakeTranslation({50, 100, 0}));
149  contents.SetEffectTransform(Matrix::MakeScale({2, 2, 1}));
150  contents.SetRenderingMode(
151  Entity::RenderingMode::kSubpassAppendSnapshotTransform);
152 
153  Entity entity;
154  entity.SetTransform(Matrix::MakeTranslation({100, 200, 0}));
155 
156  std::shared_ptr<ContentContext> renderer = GetContentContext();
157  std::optional<Entity> result =
158  contents.GetEntity(*renderer, entity, /*coverage_hint=*/{});
159  expectRenderCoverageEqual(result, contents.GetCoverage(entity),
160  Rect::MakeXYWH(200, 400, 100, 100));
161 }

References impeller::FilterContents::GetCoverage(), impeller::FilterContents::GetEntity(), impeller::Entity::kSubpassAppendSnapshotTransform, impeller::FilterInput::Make(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeTranslation(), impeller::TRect< Scalar >::MakeXYWH(), impeller::FilterContents::SetEffectTransform(), impeller::FilterContents::SetInputs(), impeller::MatrixFilterContents::SetMatrix(), impeller::MatrixFilterContents::SetRenderingMode(), and impeller::Entity::SetTransform().

◆ TEST_P() [397/454]

impeller::testing::TEST_P ( MatrixFilterContentsTest  ,
RenderCoverageMatchesGetCoverageIdentity   
)

Definition at line 111 of file matrix_filter_contents_unittests.cc.

111  {
112  std::shared_ptr<Texture> texture = MakeTexture(ISize(100, 100));
113  MatrixFilterContents contents;
114  contents.SetInputs({FilterInput::Make(texture)});
115 
116  Entity entity;
117  entity.SetTransform(Matrix::MakeTranslation({100, 200, 0}));
118 
119  std::shared_ptr<ContentContext> renderer = GetContentContext();
120  std::optional<Entity> result =
121  contents.GetEntity(*renderer, entity, /*coverage_hint=*/{});
122  expectRenderCoverageEqual(result, contents.GetCoverage(entity),
123  Rect::MakeXYWH(100, 200, 100, 100));
124 }

References impeller::FilterContents::GetCoverage(), impeller::FilterContents::GetEntity(), impeller::FilterInput::Make(), impeller::Matrix::MakeTranslation(), impeller::TRect< Scalar >::MakeXYWH(), impeller::FilterContents::SetInputs(), and impeller::Entity::SetTransform().

◆ TEST_P() [398/454]

impeller::testing::TEST_P ( MatrixFilterContentsTest  ,
RenderCoverageMatchesGetCoverageScale   
)

Definition at line 163 of file matrix_filter_contents_unittests.cc.

163  {
164  std::shared_ptr<Texture> texture = MakeTexture(ISize(100, 100));
165  MatrixFilterContents contents;
166  contents.SetInputs({FilterInput::Make(texture)});
167  contents.SetMatrix(Matrix::MakeScale({3, 3, 1}));
168  contents.SetEffectTransform(Matrix::MakeScale({2, 2, 1}));
169 
170  Entity entity;
171  entity.SetTransform(Matrix::MakeTranslation({100, 200, 0}));
172 
173  std::shared_ptr<ContentContext> renderer = GetContentContext();
174  std::optional<Entity> result =
175  contents.GetEntity(*renderer, entity, /*coverage_hint=*/{});
176  expectRenderCoverageEqual(result, contents.GetCoverage(entity),
177  Rect::MakeXYWH(100, 200, 300, 300));
178 }

References impeller::FilterContents::GetCoverage(), impeller::FilterContents::GetEntity(), impeller::FilterInput::Make(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeTranslation(), impeller::TRect< Scalar >::MakeXYWH(), impeller::FilterContents::SetEffectTransform(), impeller::FilterContents::SetInputs(), impeller::MatrixFilterContents::SetMatrix(), and impeller::Entity::SetTransform().

◆ TEST_P() [399/454]

impeller::testing::TEST_P ( MatrixFilterContentsTest  ,
RenderCoverageMatchesGetCoverageSubpassScale   
)

Definition at line 200 of file matrix_filter_contents_unittests.cc.

200  {
201  std::shared_ptr<Texture> texture = MakeTexture(ISize(100, 100));
202  MatrixFilterContents contents;
203  contents.SetInputs({FilterInput::Make(texture)});
204  contents.SetMatrix(Matrix::MakeScale({3, 3, 1}));
205  contents.SetEffectTransform(Matrix::MakeScale({2, 2, 1}));
206  contents.SetRenderingMode(
207  Entity::RenderingMode::kSubpassPrependSnapshotTransform);
208 
209  Entity entity;
210  entity.SetTransform(Matrix::MakeTranslation({100, 200, 0}));
211 
212  std::shared_ptr<ContentContext> renderer = GetContentContext();
213  std::optional<Entity> result =
214  contents.GetEntity(*renderer, entity, /*coverage_hint=*/{});
215  expectRenderCoverageEqual(result, contents.GetCoverage(entity),
216  Rect::MakeXYWH(300, 600, 300, 300));
217 }

References impeller::FilterContents::GetCoverage(), impeller::FilterContents::GetEntity(), impeller::Entity::kSubpassPrependSnapshotTransform, impeller::FilterInput::Make(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeTranslation(), impeller::TRect< Scalar >::MakeXYWH(), impeller::FilterContents::SetEffectTransform(), impeller::FilterContents::SetInputs(), impeller::MatrixFilterContents::SetMatrix(), impeller::MatrixFilterContents::SetRenderingMode(), and impeller::Entity::SetTransform().

◆ TEST_P() [400/454]

impeller::testing::TEST_P ( MatrixFilterContentsTest  ,
RenderCoverageMatchesGetCoverageTranslate   
)

Definition at line 126 of file matrix_filter_contents_unittests.cc.

126  {
127  std::shared_ptr<Texture> texture = MakeTexture(ISize(100, 100));
128  MatrixFilterContents contents;
129  contents.SetInputs({FilterInput::Make(texture)});
130  contents.SetMatrix(Matrix::MakeTranslation({50, 100, 0}));
131  contents.SetEffectTransform(Matrix::MakeScale({2, 2, 1}));
132 
133  Entity entity;
134  entity.SetTransform(Matrix::MakeTranslation({100, 200, 0}));
135 
136  std::shared_ptr<ContentContext> renderer = GetContentContext();
137  std::optional<Entity> result =
138  contents.GetEntity(*renderer, entity, /*coverage_hint=*/{});
139  expectRenderCoverageEqual(result, contents.GetCoverage(entity),
140  Rect::MakeXYWH(150, 300, 100, 100));
141 }

References impeller::FilterContents::GetCoverage(), impeller::FilterContents::GetEntity(), impeller::FilterInput::Make(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeTranslation(), impeller::TRect< Scalar >::MakeXYWH(), impeller::FilterContents::SetEffectTransform(), impeller::FilterContents::SetInputs(), impeller::MatrixFilterContents::SetMatrix(), and impeller::Entity::SetTransform().

◆ TEST_P() [401/454]

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 }

References impeller::BackendCast< SurfaceContextVK, Context >::Cast(), impeller::BackendCast< ContextVK, Context >::Cast(), impeller::BackendCast< CapabilitiesVK, Capabilities >::Cast(), impeller::PipelineCacheDataPersist(), and impeller::PipelineCacheDataRetrieve().

◆ TEST_P() [402/454]

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< SurfaceContextVK, Context >::Cast(), impeller::BackendCast< ContextVK, Context >::Cast(), impeller::BackendCast< CapabilitiesVK, Capabilities >::Cast(), impeller::PipelineCacheDataPersist(), and impeller::PipelineCacheDataRetrieve().

◆ TEST_P() [403/454]

impeller::testing::TEST_P ( RendererDartTest  ,
CanCreateRenderPassAndSubmit   
)

Definition at line 302 of file renderer_dart_unittests.cc.

302  {
303  ASSERT_TRUE(RenderDartToPlayground("canCreateRenderPassAndSubmit"));
304 }

◆ TEST_P() [404/454]

impeller::testing::TEST_P ( RendererDartTest  ,
CanCreateShaderLibrary   
)

Definition at line 290 of file renderer_dart_unittests.cc.

290  {
291  ASSERT_TRUE(RunDartFunction("canCreateShaderLibrary"));
292 }

◆ TEST_P() [405/454]

impeller::testing::TEST_P ( RendererDartTest  ,
CanInstantiateFlutterGPUContext   
)

These test entries correspond to Dart functions located in flutter/impeller/fixtures/dart_tests.dart

Definition at line 286 of file renderer_dart_unittests.cc.

286  {
287  ASSERT_TRUE(RunDartFunction("instantiateDefaultContext"));
288 }

◆ TEST_P() [406/454]

impeller::testing::TEST_P ( RendererDartTest  ,
CanReflectUniformStructs   
)

Definition at line 294 of file renderer_dart_unittests.cc.

294  {
295  ASSERT_TRUE(RunDartFunction("canReflectUniformStructs"));
296 }

◆ TEST_P() [407/454]

impeller::testing::TEST_P ( RendererDartTest  ,
CanRunDartInPlaygroundFrame   
)

Definition at line 271 of file renderer_dart_unittests.cc.

271  {
272  SinglePassCallback callback = [&](RenderPass& pass) {
273  ImGui::Begin("Dart test", nullptr);
274  ImGui::Text(
275  "This test executes Dart code during the playground frame callback.");
276  ImGui::End();
277 
278  return RunDartFunction("sayHi");
279  };
280  ASSERT_TRUE(OpenPlaygroundHere(callback));
281 }

◆ TEST_P() [408/454]

impeller::testing::TEST_P ( RendererDartTest  ,
UniformBindFailsForInvalidHostBufferOffset   
)

Definition at line 298 of file renderer_dart_unittests.cc.

298  {
299  ASSERT_TRUE(RunDartFunction("uniformBindFailsForInvalidHostBufferOffset"));
300 }

◆ TEST_P() [409/454]

impeller::testing::TEST_P ( RendererTest  ,
ArrayUniforms   
)

Definition at line 997 of file renderer_unittests.cc.

997  {
998  using VS = ArrayVertexShader;
999  using FS = ArrayFragmentShader;
1000 
1001  auto context = GetContext();
1002  auto pipeline_descriptor =
1003  PipelineBuilder<VS, FS>::MakeDefaultPipelineDescriptor(*context);
1004  ASSERT_TRUE(pipeline_descriptor.has_value());
1005  pipeline_descriptor->SetSampleCount(SampleCount::kCount4);
1006  pipeline_descriptor->SetStencilAttachmentDescriptors(std::nullopt);
1007  auto pipeline =
1008  context->GetPipelineLibrary()->GetPipeline(pipeline_descriptor).Get();
1009  ASSERT_TRUE(pipeline && pipeline->IsValid());
1010 
1011  auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
1012  SinglePassCallback callback = [&](RenderPass& pass) {
1013  auto size = pass.GetRenderTargetSize();
1014 
1015  pass.SetPipeline(pipeline);
1016  pass.SetCommandLabel("Google Dots");
1017  VertexBufferBuilder<VS::PerVertexData> builder;
1018  builder.AddVertices({{Point()},
1019  {Point(0, size.height)},
1020  {Point(size.width, 0)},
1021  {Point(size.width, 0)},
1022  {Point(0, size.height)},
1023  {Point(size.width, size.height)}});
1024  pass.SetVertexBuffer(builder.CreateVertexBuffer(*host_buffer));
1025 
1026  VS::FrameInfo frame_info;
1027  EXPECT_EQ(pass.GetOrthographicTransform(), Matrix::MakeOrthographic(size));
1028  frame_info.mvp =
1029  pass.GetOrthographicTransform() * Matrix::MakeScale(GetContentScale());
1030  VS::BindFrameInfo(pass, host_buffer->EmplaceUniform(frame_info));
1031 
1032  auto time = GetSecondsElapsed();
1033  auto y_pos = [&time](float x) {
1034  return 400 + 10 * std::cos(time * 5 + x / 6);
1035  };
1036 
1037  FS::FragInfo fs_uniform = {
1038  .circle_positions = {Point(430, y_pos(0)), Point(480, y_pos(1)),
1039  Point(530, y_pos(2)), Point(580, y_pos(3))},
1040  .colors = {Color::MakeRGBA8(66, 133, 244, 255),
1041  Color::MakeRGBA8(219, 68, 55, 255),
1042  Color::MakeRGBA8(244, 180, 0, 255),
1043  Color::MakeRGBA8(15, 157, 88, 255)},
1044  };
1045  FS::BindFragInfo(pass, host_buffer->EmplaceUniform(fs_uniform));
1046 
1047  pass.Draw();
1048  host_buffer->Reset();
1049  return true;
1050  };
1051  OpenPlaygroundHere(callback);
1052 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), impeller::HostBuffer::Create(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::CreateVertexBuffer(), impeller::kCount4, impeller::PipelineBuilder< VertexShader_, FragmentShader_ >::MakeDefaultPipelineDescriptor(), impeller::Matrix::MakeOrthographic(), impeller::Color::MakeRGBA8(), and impeller::Matrix::MakeScale().

◆ TEST_P() [410/454]

impeller::testing::TEST_P ( RendererTest  ,
BabysFirstTriangle   
)

Definition at line 123 of file renderer_unittests.cc.

123  {
124  auto context = GetContext();
125  ASSERT_TRUE(context);
126 
127  // Declare a shorthand for the shaders we are going to use.
128  using VS = BabyVertexShader;
129  using FS = BabyFragmentShader;
130 
131  // Create a pipeline descriptor that uses the shaders together and default
132  // initializes the fixed function state.
133  //
134  // If the vertex shader outputs disagree with the fragment shader inputs, this
135  // will be a compile time error.
136  auto desc = PipelineBuilder<VS, FS>::MakeDefaultPipelineDescriptor(*context);
137  ASSERT_TRUE(desc.has_value());
138 
139  // Modify the descriptor for our environment. This is specific to our test.
140  desc->SetSampleCount(SampleCount::kCount4);
141  desc->SetStencilAttachmentDescriptors(std::nullopt);
142 
143  // Create a pipeline from our descriptor. This is expensive to do. So just do
144  // it once.
145  auto pipeline = context->GetPipelineLibrary()->GetPipeline(desc).Get();
146 
147  // Create a host side buffer to build the vertex and uniform information.
148  auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
149 
150  // Specify the vertex buffer information.
151  VertexBufferBuilder<VS::PerVertexData> vertex_buffer_builder;
152  vertex_buffer_builder.AddVertices({
153  {{-0.5, -0.5}, Color::Red(), Color::Green()},
154  {{0.0, 0.5}, Color::Green(), Color::Blue()},
155  {{0.5, -0.5}, Color::Blue(), Color::Red()},
156  });
157 
158  auto vertex_buffer = vertex_buffer_builder.CreateVertexBuffer(
159  *context->GetResourceAllocator());
160 
161  SinglePassCallback callback = [&](RenderPass& pass) {
162  pass.SetPipeline(pipeline);
163  pass.SetVertexBuffer(vertex_buffer);
164 
165  FS::FragInfo frag_info;
166  frag_info.time = fml::TimePoint::Now().ToEpochDelta().ToSecondsF();
167 
168  auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
169  FS::BindFragInfo(pass, host_buffer->EmplaceUniform(frag_info));
170 
171  return pass.Draw().ok();
172  };
173  OpenPlaygroundHere(callback);
174 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), impeller::Color::Blue(), impeller::HostBuffer::Create(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::CreateVertexBuffer(), impeller::Color::Green(), impeller::kCount4, impeller::PipelineBuilder< VertexShader_, FragmentShader_ >::MakeDefaultPipelineDescriptor(), and impeller::Color::Red().

◆ TEST_P() [411/454]

impeller::testing::TEST_P ( RendererTest  ,
CachesRenderPassAndFramebuffer   
)

Definition at line 16 of file render_pass_cache_unittests.cc.

16  {
17  if (GetBackend() != PlaygroundBackend::kVulkan) {
18  GTEST_SKIP() << "Test only applies to Vulkan";
19  }
20 
21  auto allocator = std::make_shared<RenderTargetAllocator>(
22  GetContext()->GetResourceAllocator());
23 
24  auto render_target =
25  allocator->CreateOffscreenMSAA(*GetContext(), {100, 100}, 1);
26  auto resolve_texture =
27  render_target.GetColorAttachments().find(0u)->second.resolve_texture;
28  auto& texture_vk = TextureVK::Cast(*resolve_texture);
29 
30  EXPECT_EQ(texture_vk.GetCachedFramebuffer(), nullptr);
31  EXPECT_EQ(texture_vk.GetCachedRenderPass(), nullptr);
32 
33  auto buffer = GetContext()->CreateCommandBuffer();
34  auto render_pass = buffer->CreateRenderPass(render_target);
35 
36  EXPECT_NE(texture_vk.GetCachedFramebuffer(), nullptr);
37  EXPECT_NE(texture_vk.GetCachedRenderPass(), nullptr);
38 
39  render_pass->EncodeCommands();
40  GetContext()->GetCommandQueue()->Submit({buffer});
41 
42  // Can be reused without error.
43  auto buffer_2 = GetContext()->CreateCommandBuffer();
44  auto render_pass_2 = buffer_2->CreateRenderPass(render_target);
45 
46  EXPECT_TRUE(render_pass_2->EncodeCommands());
47  EXPECT_TRUE(GetContext()->GetCommandQueue()->Submit({buffer_2}).ok());
48 }

References impeller::BackendCast< TextureVK, Texture >::Cast(), and impeller::kVulkan.

◆ TEST_P() [412/454]

impeller::testing::TEST_P ( RendererTest  ,
CanBlitTextureToBuffer   
)

Definition at line 613 of file renderer_unittests.cc.

613  {
614  if (GetBackend() == PlaygroundBackend::kOpenGLES) {
615  GTEST_SKIP() << "Mipmap test shader not supported on GLES.";
616  }
617  auto context = GetContext();
618  ASSERT_TRUE(context);
619 
620  using VS = MipmapsVertexShader;
621  using FS = MipmapsFragmentShader;
622  auto desc = PipelineBuilder<VS, FS>::MakeDefaultPipelineDescriptor(*context);
623  ASSERT_TRUE(desc.has_value());
624  desc->SetSampleCount(SampleCount::kCount4);
625  desc->SetStencilAttachmentDescriptors(std::nullopt);
626  auto mipmaps_pipeline =
627  context->GetPipelineLibrary()->GetPipeline(std::move(desc)).Get();
628  ASSERT_TRUE(mipmaps_pipeline);
629 
630  auto bridge = CreateTextureForFixture("bay_bridge.jpg");
631  auto boston = CreateTextureForFixture("boston.jpg");
632  ASSERT_TRUE(bridge && boston);
633  const std::unique_ptr<const Sampler>& sampler =
634  context->GetSamplerLibrary()->GetSampler({});
635  ASSERT_TRUE(sampler);
636 
637  TextureDescriptor texture_desc;
638  texture_desc.storage_mode = StorageMode::kHostVisible;
639  texture_desc.format = PixelFormat::kR8G8B8A8UNormInt;
640  texture_desc.size = bridge->GetTextureDescriptor().size;
641  texture_desc.mip_count = 1u;
642  texture_desc.usage = TextureUsage::kRenderTarget |
643  TextureUsage::kShaderWrite | TextureUsage::kShaderRead;
644  DeviceBufferDescriptor device_buffer_desc;
645  device_buffer_desc.storage_mode = StorageMode::kHostVisible;
646  device_buffer_desc.size =
647  bridge->GetTextureDescriptor().GetByteSizeOfBaseMipLevel();
648  auto device_buffer =
649  context->GetResourceAllocator()->CreateBuffer(device_buffer_desc);
650 
651  // Vertex buffer.
652  VertexBufferBuilder<VS::PerVertexData> vertex_builder;
653  vertex_builder.SetLabel("Box");
654  auto size = Point(boston->GetSize());
655  vertex_builder.AddVertices({
656  {{0, 0}, {0.0, 0.0}}, // 1
657  {{size.x, 0}, {1.0, 0.0}}, // 2
658  {{size.x, size.y}, {1.0, 1.0}}, // 3
659  {{0, 0}, {0.0, 0.0}}, // 1
660  {{size.x, size.y}, {1.0, 1.0}}, // 3
661  {{0, size.y}, {0.0, 1.0}}, // 4
662  });
663  auto vertex_buffer =
664  vertex_builder.CreateVertexBuffer(*context->GetResourceAllocator());
665  ASSERT_TRUE(vertex_buffer);
666 
667  auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
668  Playground::RenderCallback callback = [&](RenderTarget& render_target) {
669  {
670  auto buffer = context->CreateCommandBuffer();
671  if (!buffer) {
672  return false;
673  }
674  buffer->SetLabel("Playground Command Buffer");
675  auto pass = buffer->CreateBlitPass();
676  if (!pass) {
677  return false;
678  }
679  pass->SetLabel("Playground Blit Pass");
680 
681  if (render_target.GetColorAttachments().empty()) {
682  return false;
683  }
684 
685  // Blit `bridge` to the top left corner of the texture.
686  pass->AddCopy(bridge, device_buffer);
687  pass->EncodeCommands(context->GetResourceAllocator());
688 
689  if (!context->GetCommandQueue()->Submit({buffer}).ok()) {
690  return false;
691  }
692  }
693 
694  {
695  auto buffer = context->CreateCommandBuffer();
696  if (!buffer) {
697  return false;
698  }
699  buffer->SetLabel("Playground Command Buffer");
700 
701  auto pass = buffer->CreateRenderPass(render_target);
702  if (!pass) {
703  return false;
704  }
705  pass->SetLabel("Playground Render Pass");
706  {
707  pass->SetCommandLabel("Image");
708  pass->SetPipeline(mipmaps_pipeline);
709  pass->SetVertexBuffer(vertex_buffer);
710 
711  VS::FrameInfo frame_info;
712  EXPECT_EQ(pass->GetOrthographicTransform(),
713  Matrix::MakeOrthographic(pass->GetRenderTargetSize()));
714  frame_info.mvp = pass->GetOrthographicTransform() *
715  Matrix::MakeScale(GetContentScale());
716  VS::BindFrameInfo(*pass, host_buffer->EmplaceUniform(frame_info));
717 
718  FS::FragInfo frag_info;
719  frag_info.lod = 0;
720  FS::BindFragInfo(*pass, host_buffer->EmplaceUniform(frag_info));
721 
722  const std::unique_ptr<const Sampler>& sampler =
723  context->GetSamplerLibrary()->GetSampler({});
724  auto buffer_view = DeviceBuffer::AsBufferView(device_buffer);
725  auto texture =
726  context->GetResourceAllocator()->CreateTexture(texture_desc);
727  if (!texture->SetContents(device_buffer->OnGetContents(),
728  buffer_view.range.length)) {
729  VALIDATION_LOG << "Could not upload texture to device memory";
730  return false;
731  }
732  FS::BindTex(*pass, texture, sampler);
733 
734  pass->Draw().ok();
735  }
736  pass->EncodeCommands();
737  if (!context->GetCommandQueue()->Submit({buffer}).ok()) {
738  return false;
739  }
740  }
741  host_buffer->Reset();
742  return true;
743  };
744  OpenPlaygroundHere(callback);
745 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), impeller::DeviceBuffer::AsBufferView(), buffer_view, impeller::HostBuffer::Create(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::CreateVertexBuffer(), impeller::TextureDescriptor::format, impeller::kCount4, impeller::kHostVisible, impeller::kOpenGLES, impeller::kR8G8B8A8UNormInt, impeller::kRenderTarget, impeller::kShaderRead, impeller::kShaderWrite, impeller::PipelineBuilder< VertexShader_, FragmentShader_ >::MakeDefaultPipelineDescriptor(), impeller::Matrix::MakeOrthographic(), impeller::Matrix::MakeScale(), impeller::TextureDescriptor::mip_count, impeller::VertexBufferBuilder< VertexType_, IndexType_ >::SetLabel(), impeller::DeviceBufferDescriptor::size, impeller::TextureDescriptor::size, impeller::DeviceBufferDescriptor::storage_mode, impeller::TextureDescriptor::storage_mode, impeller::TextureDescriptor::usage, and VALIDATION_LOG.

◆ TEST_P() [413/454]

impeller::testing::TEST_P ( RendererTest  ,
CanBlitTextureToTexture   
)

Definition at line 498 of file renderer_unittests.cc.

498  {
499  if (GetBackend() == PlaygroundBackend::kOpenGLES) {
500  GTEST_SKIP() << "Mipmap test shader not supported on GLES.";
501  }
502  auto context = GetContext();
503  ASSERT_TRUE(context);
504 
505  using VS = MipmapsVertexShader;
506  using FS = MipmapsFragmentShader;
507  auto desc = PipelineBuilder<VS, FS>::MakeDefaultPipelineDescriptor(*context);
508  ASSERT_TRUE(desc.has_value());
509  desc->SetSampleCount(SampleCount::kCount4);
510  desc->SetStencilAttachmentDescriptors(std::nullopt);
511  auto mipmaps_pipeline =
512  context->GetPipelineLibrary()->GetPipeline(std::move(desc)).Get();
513  ASSERT_TRUE(mipmaps_pipeline);
514 
515  TextureDescriptor texture_desc;
516  texture_desc.storage_mode = StorageMode::kHostVisible;
517  texture_desc.format = PixelFormat::kR8G8B8A8UNormInt;
518  texture_desc.size = {800, 600};
519  texture_desc.mip_count = 1u;
520  texture_desc.usage = TextureUsage::kRenderTarget | TextureUsage::kShaderRead;
521  auto texture = context->GetResourceAllocator()->CreateTexture(texture_desc);
522  ASSERT_TRUE(texture);
523 
524  auto bridge = CreateTextureForFixture("bay_bridge.jpg");
525  auto boston = CreateTextureForFixture("boston.jpg");
526  ASSERT_TRUE(bridge && boston);
527  const std::unique_ptr<const Sampler>& sampler =
528  context->GetSamplerLibrary()->GetSampler({});
529  ASSERT_TRUE(sampler);
530 
531  // Vertex buffer.
532  VertexBufferBuilder<VS::PerVertexData> vertex_builder;
533  vertex_builder.SetLabel("Box");
534  auto size = Point(boston->GetSize());
535  vertex_builder.AddVertices({
536  {{0, 0}, {0.0, 0.0}}, // 1
537  {{size.x, 0}, {1.0, 0.0}}, // 2
538  {{size.x, size.y}, {1.0, 1.0}}, // 3
539  {{0, 0}, {0.0, 0.0}}, // 1
540  {{size.x, size.y}, {1.0, 1.0}}, // 3
541  {{0, size.y}, {0.0, 1.0}}, // 4
542  });
543  auto vertex_buffer =
544  vertex_builder.CreateVertexBuffer(*context->GetResourceAllocator());
545  ASSERT_TRUE(vertex_buffer);
546 
547  auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
548  Playground::RenderCallback callback = [&](RenderTarget& render_target) {
549  auto buffer = context->CreateCommandBuffer();
550  if (!buffer) {
551  return false;
552  }
553  buffer->SetLabel("Playground Command Buffer");
554 
555  {
556  auto pass = buffer->CreateBlitPass();
557  if (!pass) {
558  return false;
559  }
560  pass->SetLabel("Playground Blit Pass");
561 
562  if (render_target.GetColorAttachments().empty()) {
563  return false;
564  }
565 
566  // Blit `bridge` to the top left corner of the texture.
567  pass->AddCopy(bridge, texture);
568 
569  if (!pass->EncodeCommands(context->GetResourceAllocator())) {
570  return false;
571  }
572  }
573 
574  {
575  auto pass = buffer->CreateRenderPass(render_target);
576  if (!pass) {
577  return false;
578  }
579  pass->SetLabel("Playground Render Pass");
580  {
581  pass->SetCommandLabel("Image");
582  pass->SetPipeline(mipmaps_pipeline);
583  pass->SetVertexBuffer(vertex_buffer);
584 
585  VS::FrameInfo frame_info;
586  EXPECT_EQ(pass->GetOrthographicTransform(),
587  Matrix::MakeOrthographic(pass->GetRenderTargetSize()));
588  frame_info.mvp = pass->GetOrthographicTransform() *
589  Matrix::MakeScale(GetContentScale());
590  VS::BindFrameInfo(*pass, host_buffer->EmplaceUniform(frame_info));
591 
592  FS::FragInfo frag_info;
593  frag_info.lod = 0;
594  FS::BindFragInfo(*pass, host_buffer->EmplaceUniform(frag_info));
595 
596  auto& sampler = context->GetSamplerLibrary()->GetSampler({});
597  FS::BindTex(*pass, texture, sampler);
598 
599  pass->Draw();
600  }
601  pass->EncodeCommands();
602  }
603 
604  if (!context->GetCommandQueue()->Submit({buffer}).ok()) {
605  return false;
606  }
607  host_buffer->Reset();
608  return true;
609  };
610  OpenPlaygroundHere(callback);
611 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), impeller::HostBuffer::Create(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::CreateVertexBuffer(), impeller::TextureDescriptor::format, impeller::kCount4, impeller::kHostVisible, impeller::kOpenGLES, impeller::kR8G8B8A8UNormInt, impeller::kRenderTarget, impeller::kShaderRead, impeller::PipelineBuilder< VertexShader_, FragmentShader_ >::MakeDefaultPipelineDescriptor(), impeller::Matrix::MakeOrthographic(), impeller::Matrix::MakeScale(), impeller::TextureDescriptor::mip_count, impeller::VertexBufferBuilder< VertexType_, IndexType_ >::SetLabel(), impeller::TextureDescriptor::size, impeller::TextureDescriptor::storage_mode, and impeller::TextureDescriptor::usage.

◆ TEST_P() [414/454]

impeller::testing::TEST_P ( RendererTest  ,
CanCreateBoxPrimitive   
)

Definition at line 54 of file renderer_unittests.cc.

54  {
55  using VS = BoxFadeVertexShader;
56  using FS = BoxFadeFragmentShader;
57  auto context = GetContext();
58  ASSERT_TRUE(context);
59  using BoxPipelineBuilder = PipelineBuilder<VS, FS>;
60  auto desc = BoxPipelineBuilder::MakeDefaultPipelineDescriptor(*context);
61  ASSERT_TRUE(desc.has_value());
62  desc->SetSampleCount(SampleCount::kCount4);
63  desc->SetStencilAttachmentDescriptors(std::nullopt);
64 
65  // Vertex buffer.
66  VertexBufferBuilder<VS::PerVertexData> vertex_builder;
67  vertex_builder.SetLabel("Box");
68  vertex_builder.AddVertices({
69  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
70  {{800, 100, 0.0}, {1.0, 0.0}}, // 2
71  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
72  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
73  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
74  {{100, 800, 0.0}, {0.0, 1.0}}, // 4
75  });
76  auto bridge = CreateTextureForFixture("bay_bridge.jpg");
77  auto boston = CreateTextureForFixture("boston.jpg");
78  ASSERT_TRUE(bridge && boston);
79  const std::unique_ptr<const Sampler>& sampler =
80  context->GetSamplerLibrary()->GetSampler({});
81  ASSERT_TRUE(sampler);
82 
83  auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
84  SinglePassCallback callback = [&](RenderPass& pass) {
85  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
86  static bool wireframe;
87  ImGui::Checkbox("Wireframe", &wireframe);
88  ImGui::End();
89 
90  desc->SetPolygonMode(wireframe ? PolygonMode::kLine : PolygonMode::kFill);
91  auto pipeline = context->GetPipelineLibrary()->GetPipeline(desc).Get();
92 
93  assert(pipeline && pipeline->IsValid());
94 
95  pass.SetCommandLabel("Box");
96  pass.SetPipeline(pipeline);
97  pass.SetVertexBuffer(
98  vertex_builder.CreateVertexBuffer(*context->GetResourceAllocator()));
99 
100  VS::UniformBuffer uniforms;
101  EXPECT_EQ(pass.GetOrthographicTransform(),
102  Matrix::MakeOrthographic(pass.GetRenderTargetSize()));
103  uniforms.mvp =
104  pass.GetOrthographicTransform() * Matrix::MakeScale(GetContentScale());
105  VS::BindUniformBuffer(pass, host_buffer->EmplaceUniform(uniforms));
106 
107  FS::FrameInfo frame_info;
108  frame_info.current_time = GetSecondsElapsed();
109  frame_info.cursor_position = GetCursorPosition();
110  frame_info.window_size.x = GetWindowSize().width;
111  frame_info.window_size.y = GetWindowSize().height;
112 
113  FS::BindFrameInfo(pass, host_buffer->EmplaceUniform(frame_info));
114  FS::BindContents1(pass, boston, sampler);
115  FS::BindContents2(pass, bridge, sampler);
116 
117  host_buffer->Reset();
118  return pass.Draw().ok();
119  };
120  OpenPlaygroundHere(callback);
121 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), impeller::HostBuffer::Create(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::CreateVertexBuffer(), impeller::kCount4, impeller::kFill, impeller::kLine, impeller::Matrix::MakeOrthographic(), impeller::Matrix::MakeScale(), and impeller::VertexBufferBuilder< VertexType_, IndexType_ >::SetLabel().

◆ TEST_P() [415/454]

impeller::testing::TEST_P ( RendererTest  ,
CanGenerateMipmaps   
)

Definition at line 747 of file renderer_unittests.cc.

747  {
748  if (GetBackend() == PlaygroundBackend::kOpenGLES) {
749  GTEST_SKIP() << "Mipmap test shader not supported on GLES.";
750  }
751  auto context = GetContext();
752  ASSERT_TRUE(context);
753 
754  using VS = MipmapsVertexShader;
755  using FS = MipmapsFragmentShader;
756  auto desc = PipelineBuilder<VS, FS>::MakeDefaultPipelineDescriptor(*context);
757  ASSERT_TRUE(desc.has_value());
758  desc->SetSampleCount(SampleCount::kCount4);
759  desc->SetStencilAttachmentDescriptors(std::nullopt);
760  auto mipmaps_pipeline =
761  context->GetPipelineLibrary()->GetPipeline(std::move(desc)).Get();
762  ASSERT_TRUE(mipmaps_pipeline);
763 
764  auto boston = CreateTextureForFixture("boston.jpg", true);
765  ASSERT_TRUE(boston);
766 
767  // Vertex buffer.
768  VertexBufferBuilder<VS::PerVertexData> vertex_builder;
769  vertex_builder.SetLabel("Box");
770  auto size = Point(boston->GetSize());
771  vertex_builder.AddVertices({
772  {{0, 0}, {0.0, 0.0}}, // 1
773  {{size.x, 0}, {1.0, 0.0}}, // 2
774  {{size.x, size.y}, {1.0, 1.0}}, // 3
775  {{0, 0}, {0.0, 0.0}}, // 1
776  {{size.x, size.y}, {1.0, 1.0}}, // 3
777  {{0, size.y}, {0.0, 1.0}}, // 4
778  });
779  auto vertex_buffer =
780  vertex_builder.CreateVertexBuffer(*context->GetResourceAllocator());
781  ASSERT_TRUE(vertex_buffer);
782 
783  bool first_frame = true;
784  auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
785  Playground::RenderCallback callback = [&](RenderTarget& render_target) {
786  const char* mip_filter_names[] = {"Base", "Nearest", "Linear"};
787  const MipFilter mip_filters[] = {MipFilter::kBase, MipFilter::kNearest,
788  MipFilter::kLinear};
789  const char* min_filter_names[] = {"Nearest", "Linear"};
790  const MinMagFilter min_filters[] = {MinMagFilter::kNearest,
791  MinMagFilter::kLinear};
792 
793  // UI state.
794  static int selected_mip_filter = 1;
795  static int selected_min_filter = 0;
796  static float lod = 4.5;
797 
798  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
799  ImGui::Combo("Mip filter", &selected_mip_filter, mip_filter_names,
800  sizeof(mip_filter_names) / sizeof(char*));
801  ImGui::Combo("Min filter", &selected_min_filter, min_filter_names,
802  sizeof(min_filter_names) / sizeof(char*));
803  ImGui::SliderFloat("LOD", &lod, 0, boston->GetMipCount() - 1);
804  ImGui::End();
805 
806  auto buffer = context->CreateCommandBuffer();
807  if (!buffer) {
808  return false;
809  }
810  buffer->SetLabel("Playground Command Buffer");
811 
812  if (first_frame) {
813  auto pass = buffer->CreateBlitPass();
814  if (!pass) {
815  return false;
816  }
817  pass->SetLabel("Playground Blit Pass");
818 
819  pass->GenerateMipmap(boston, "Boston Mipmap");
820 
821  pass->EncodeCommands(context->GetResourceAllocator());
822  }
823 
824  first_frame = false;
825 
826  {
827  auto pass = buffer->CreateRenderPass(render_target);
828  if (!pass) {
829  return false;
830  }
831  pass->SetLabel("Playground Render Pass");
832  {
833  pass->SetCommandLabel("Image LOD");
834  pass->SetPipeline(mipmaps_pipeline);
835  pass->SetVertexBuffer(vertex_buffer);
836 
837  VS::FrameInfo frame_info;
838  EXPECT_EQ(pass->GetOrthographicTransform(),
839  Matrix::MakeOrthographic(pass->GetRenderTargetSize()));
840  frame_info.mvp = pass->GetOrthographicTransform() *
841  Matrix::MakeScale(GetContentScale());
842  VS::BindFrameInfo(*pass, host_buffer->EmplaceUniform(frame_info));
843 
844  FS::FragInfo frag_info;
845  frag_info.lod = lod;
846  FS::BindFragInfo(*pass, host_buffer->EmplaceUniform(frag_info));
847 
848  SamplerDescriptor sampler_desc;
849  sampler_desc.mip_filter = mip_filters[selected_mip_filter];
850  sampler_desc.min_filter = min_filters[selected_min_filter];
851  const std::unique_ptr<const Sampler>& sampler =
852  context->GetSamplerLibrary()->GetSampler(sampler_desc);
853  FS::BindTex(*pass, boston, sampler);
854 
855  pass->Draw();
856  }
857  pass->EncodeCommands();
858  }
859 
860  if (!context->GetCommandQueue()->Submit({buffer}).ok()) {
861  return false;
862  }
863  host_buffer->Reset();
864  return true;
865  };
866  OpenPlaygroundHere(callback);
867 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), impeller::HostBuffer::Create(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::CreateVertexBuffer(), impeller::kBase, impeller::kCount4, impeller::kLinear, impeller::kNearest, impeller::kOpenGLES, impeller::PipelineBuilder< VertexShader_, FragmentShader_ >::MakeDefaultPipelineDescriptor(), impeller::Matrix::MakeOrthographic(), impeller::Matrix::MakeScale(), impeller::SamplerDescriptor::min_filter, impeller::SamplerDescriptor::mip_filter, and impeller::VertexBufferBuilder< VertexType_, IndexType_ >::SetLabel().

◆ TEST_P() [416/454]

impeller::testing::TEST_P ( RendererTest  ,
CanLookupRenderTargetProperties   
)

Definition at line 1341 of file renderer_unittests.cc.

1341  {
1342  auto context = GetContext();
1343  auto cmd_buffer = context->CreateCommandBuffer();
1344  auto render_target_cache = std::make_shared<RenderTargetAllocator>(
1345  GetContext()->GetResourceAllocator());
1346 
1347  auto render_target = render_target_cache->CreateOffscreen(
1348  *context, {100, 100}, /*mip_count=*/1);
1349  auto render_pass = cmd_buffer->CreateRenderPass(render_target);
1350 
1351  EXPECT_EQ(render_pass->GetSampleCount(), render_target.GetSampleCount());
1352  EXPECT_EQ(render_pass->GetRenderTargetPixelFormat(),
1353  render_target.GetRenderTargetPixelFormat());
1354  EXPECT_EQ(render_pass->HasStencilAttachment(),
1355  render_target.GetStencilAttachment().has_value());
1356  EXPECT_EQ(render_pass->GetRenderTargetSize(),
1357  render_target.GetRenderTargetSize());
1358  render_pass->EncodeCommands();
1359 }

◆ TEST_P() [417/454]

impeller::testing::TEST_P ( RendererTest  ,
CanRenderInstanced   
)

Definition at line 441 of file renderer_unittests.cc.

441  {
442  if (GetParam() == PlaygroundBackend::kOpenGLES) {
443  GTEST_SKIP() << "Instancing is not supported on OpenGL.";
444  }
445  using VS = InstancedDrawVertexShader;
446  using FS = InstancedDrawFragmentShader;
447 
448  VertexBufferBuilder<VS::PerVertexData> builder;
449  builder.AddVertices({
450  VS::PerVertexData{Point{10, 10}},
451  VS::PerVertexData{Point{10, 110}},
452  VS::PerVertexData{Point{110, 10}},
453  VS::PerVertexData{Point{10, 110}},
454  VS::PerVertexData{Point{110, 10}},
455  VS::PerVertexData{Point{110, 110}},
456  });
457 
458  ASSERT_NE(GetContext(), nullptr);
459  auto pipeline =
460  GetContext()
461  ->GetPipelineLibrary()
462  ->GetPipeline(PipelineBuilder<VS, FS>::MakeDefaultPipelineDescriptor(
463  *GetContext())
464  ->SetSampleCount(SampleCount::kCount4)
465  .SetStencilAttachmentDescriptors(std::nullopt))
466 
467  .Get();
468  ASSERT_TRUE(pipeline && pipeline->IsValid());
469 
470  static constexpr size_t kInstancesCount = 5u;
471  VS::InstanceInfo<kInstancesCount> instances;
472  for (size_t i = 0; i < kInstancesCount; i++) {
473  instances.colors[i] = Color::Random();
474  }
475 
476  auto host_buffer = HostBuffer::Create(GetContext()->GetResourceAllocator());
477  ASSERT_TRUE(OpenPlaygroundHere([&](RenderPass& pass) -> bool {
478  pass.SetPipeline(pipeline);
479  pass.SetCommandLabel("InstancedDraw");
480 
481  VS::FrameInfo frame_info;
482  EXPECT_EQ(pass.GetOrthographicTransform(),
483  Matrix::MakeOrthographic(pass.GetRenderTargetSize()));
484  frame_info.mvp =
485  pass.GetOrthographicTransform() * Matrix::MakeScale(GetContentScale());
486  VS::BindFrameInfo(pass, host_buffer->EmplaceUniform(frame_info));
487  VS::BindInstanceInfo(pass, host_buffer->EmplaceStorageBuffer(instances));
488  pass.SetVertexBuffer(builder.CreateVertexBuffer(*host_buffer));
489 
490  pass.SetInstanceCount(kInstancesCount);
491  pass.Draw();
492 
493  host_buffer->Reset();
494  return true;
495  }));
496 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), impeller::HostBuffer::Create(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::CreateVertexBuffer(), impeller::RenderPass::Draw(), impeller::RenderPass::GetOrthographicTransform(), impeller::RenderPass::GetRenderTargetSize(), impeller::kCount4, impeller::kOpenGLES, impeller::Matrix::MakeOrthographic(), impeller::Matrix::MakeScale(), impeller::Color::Random(), impeller::RenderPass::SetCommandLabel(), impeller::RenderPass::SetInstanceCount(), impeller::RenderPass::SetPipeline(), and impeller::RenderPass::SetVertexBuffer().

◆ TEST_P() [418/454]

impeller::testing::TEST_P ( RendererTest  ,
CanRenderMultiplePrimitives   
)

Definition at line 265 of file renderer_unittests.cc.

265  {
266  using VS = BoxFadeVertexShader;
267  using FS = BoxFadeFragmentShader;
268  auto context = GetContext();
269  ASSERT_TRUE(context);
270  using BoxPipelineBuilder = PipelineBuilder<VS, FS>;
271  auto desc = BoxPipelineBuilder::MakeDefaultPipelineDescriptor(*context);
272  ASSERT_TRUE(desc.has_value());
273  desc->SetSampleCount(SampleCount::kCount4);
274  desc->SetStencilAttachmentDescriptors(std::nullopt);
275  auto box_pipeline =
276  context->GetPipelineLibrary()->GetPipeline(std::move(desc)).Get();
277  ASSERT_TRUE(box_pipeline);
278 
279  // Vertex buffer.
280  VertexBufferBuilder<VS::PerVertexData> vertex_builder;
281  vertex_builder.SetLabel("Box");
282  vertex_builder.AddVertices({
283  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
284  {{800, 100, 0.0}, {1.0, 0.0}}, // 2
285  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
286  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
287  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
288  {{100, 800, 0.0}, {0.0, 1.0}}, // 4
289  });
290  auto vertex_buffer =
291  vertex_builder.CreateVertexBuffer(*context->GetResourceAllocator());
292  ASSERT_TRUE(vertex_buffer);
293 
294  auto bridge = CreateTextureForFixture("bay_bridge.jpg");
295  auto boston = CreateTextureForFixture("boston.jpg");
296  ASSERT_TRUE(bridge && boston);
297  const std::unique_ptr<const Sampler>& sampler =
298  context->GetSamplerLibrary()->GetSampler({});
299  ASSERT_TRUE(sampler);
300 
301  auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
302  SinglePassCallback callback = [&](RenderPass& pass) {
303  for (size_t i = 0; i < 1; i++) {
304  for (size_t j = 0; j < 1; j++) {
305  pass.SetCommandLabel("Box");
306  pass.SetPipeline(box_pipeline);
307  pass.SetVertexBuffer(vertex_buffer);
308 
309  FS::FrameInfo frame_info;
310  frame_info.current_time = GetSecondsElapsed();
311  frame_info.cursor_position = GetCursorPosition();
312  frame_info.window_size.x = GetWindowSize().width;
313  frame_info.window_size.y = GetWindowSize().height;
314 
315  FS::BindFrameInfo(pass, host_buffer->EmplaceUniform(frame_info));
316  FS::BindContents1(pass, boston, sampler);
317  FS::BindContents2(pass, bridge, sampler);
318 
319  VS::UniformBuffer uniforms;
320  EXPECT_EQ(pass.GetOrthographicTransform(),
321  Matrix::MakeOrthographic(pass.GetRenderTargetSize()));
322  uniforms.mvp = pass.GetOrthographicTransform() *
323  Matrix::MakeScale(GetContentScale()) *
324  Matrix::MakeTranslation({i * 50.0f, j * 50.0f, 0.0f});
325  VS::BindUniformBuffer(pass, host_buffer->EmplaceUniform(uniforms));
326  if (!pass.Draw().ok()) {
327  return false;
328  }
329  }
330  }
331 
332  host_buffer->Reset();
333  return true;
334  };
335  OpenPlaygroundHere(callback);
336 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), impeller::HostBuffer::Create(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::CreateVertexBuffer(), impeller::kCount4, impeller::Matrix::MakeOrthographic(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeTranslation(), and impeller::VertexBufferBuilder< VertexType_, IndexType_ >::SetLabel().

◆ TEST_P() [419/454]

impeller::testing::TEST_P ( RendererTest  ,
CanRenderPerspectiveCube   
)

Definition at line 176 of file renderer_unittests.cc.

176  {
177  using VS = ColorsVertexShader;
178  using FS = ColorsFragmentShader;
179  auto context = GetContext();
180  ASSERT_TRUE(context);
181  auto desc = PipelineBuilder<VS, FS>::MakeDefaultPipelineDescriptor(*context);
182  ASSERT_TRUE(desc.has_value());
183  desc->SetCullMode(CullMode::kBackFace);
184  desc->SetWindingOrder(WindingOrder::kCounterClockwise);
185  desc->SetSampleCount(SampleCount::kCount4);
186  desc->SetStencilAttachmentDescriptors(std::nullopt);
187  auto pipeline =
188  context->GetPipelineLibrary()->GetPipeline(std::move(desc)).Get();
189  ASSERT_TRUE(pipeline);
190 
191  struct Cube {
192  VS::PerVertexData vertices[8] = {
193  // -Z
194  {{-1, -1, -1}, Color::Red()},
195  {{1, -1, -1}, Color::Yellow()},
196  {{1, 1, -1}, Color::Green()},
197  {{-1, 1, -1}, Color::Blue()},
198  // +Z
199  {{-1, -1, 1}, Color::Green()},
200  {{1, -1, 1}, Color::Blue()},
201  {{1, 1, 1}, Color::Red()},
202  {{-1, 1, 1}, Color::Yellow()},
203  };
204  uint16_t indices[36] = {
205  1, 5, 2, 2, 5, 6, // +X
206  4, 0, 7, 7, 0, 3, // -X
207  4, 5, 0, 0, 5, 1, // +Y
208  3, 2, 7, 7, 2, 6, // -Y
209  5, 4, 6, 6, 4, 7, // +Z
210  0, 1, 3, 3, 1, 2, // -Z
211  };
212  } cube;
213 
214  VertexBuffer vertex_buffer;
215  {
216  auto device_buffer = context->GetResourceAllocator()->CreateBufferWithCopy(
217  reinterpret_cast<uint8_t*>(&cube), sizeof(cube));
218  vertex_buffer.vertex_buffer = {
219  .buffer = device_buffer,
220  .range = Range(offsetof(Cube, vertices), sizeof(Cube::vertices))};
221  vertex_buffer.index_buffer = {
222  .buffer = device_buffer,
223  .range = Range(offsetof(Cube, indices), sizeof(Cube::indices))};
224  vertex_buffer.vertex_count = 36;
225  vertex_buffer.index_type = IndexType::k16bit;
226  }
227 
228  const std::unique_ptr<const Sampler>& sampler =
229  context->GetSamplerLibrary()->GetSampler({});
230  ASSERT_TRUE(sampler);
231 
232  Vector3 euler_angles;
233  auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
234  SinglePassCallback callback = [&](RenderPass& pass) {
235  static Degrees fov_y(60);
236  static Scalar distance = 10;
237 
238  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
239  ImGui::SliderFloat("Field of view", &fov_y.degrees, 0, 180);
240  ImGui::SliderFloat("Camera distance", &distance, 0, 30);
241  ImGui::End();
242 
243  pass.SetCommandLabel("Perspective Cube");
244  pass.SetPipeline(pipeline);
245  pass.SetVertexBuffer(vertex_buffer);
246 
247  VS::UniformBuffer uniforms;
248  Scalar time = GetSecondsElapsed();
249  euler_angles = Vector3(0.19 * time, 0.7 * time, 0.43 * time);
250 
251  uniforms.mvp =
252  Matrix::MakePerspective(fov_y, pass.GetRenderTargetSize(), 0, 10) *
253  Matrix::MakeTranslation({0, 0, distance}) *
254  Matrix::MakeRotationX(Radians(euler_angles.x)) *
255  Matrix::MakeRotationY(Radians(euler_angles.y)) *
256  Matrix::MakeRotationZ(Radians(euler_angles.z));
257  VS::BindUniformBuffer(pass, host_buffer->EmplaceUniform(uniforms));
258 
259  host_buffer->Reset();
260  return pass.Draw().ok();
261  };
262  OpenPlaygroundHere(callback);
263 }

References impeller::Color::Blue(), impeller::BufferView::buffer, impeller::HostBuffer::Create(), impeller::Degrees::degrees, impeller::saturated::distance, impeller::Color::Green(), impeller::VertexBuffer::index_buffer, impeller::VertexBuffer::index_type, impeller::k16bit, impeller::kBackFace, impeller::kCount4, impeller::kCounterClockwise, impeller::PipelineBuilder< VertexShader_, FragmentShader_ >::MakeDefaultPipelineDescriptor(), impeller::Matrix::MakePerspective(), impeller::Matrix::MakeRotationX(), impeller::Matrix::MakeRotationY(), impeller::Matrix::MakeRotationZ(), impeller::Matrix::MakeTranslation(), impeller::Color::Red(), impeller::VertexBuffer::vertex_buffer, impeller::VertexBuffer::vertex_count, impeller::Vector3::x, impeller::Vector3::y, impeller::Color::Yellow(), and impeller::Vector3::z.

◆ TEST_P() [420/454]

impeller::testing::TEST_P ( RendererTest  ,
CanRenderToTexture   
)

Definition at line 338 of file renderer_unittests.cc.

338  {
339  using VS = BoxFadeVertexShader;
340  using FS = BoxFadeFragmentShader;
341  auto context = GetContext();
342  ASSERT_TRUE(context);
343  using BoxPipelineBuilder = PipelineBuilder<VS, FS>;
344  auto pipeline_desc =
345  BoxPipelineBuilder::MakeDefaultPipelineDescriptor(*context);
346  pipeline_desc->SetSampleCount(SampleCount::kCount1);
347  pipeline_desc->ClearDepthAttachment();
348  pipeline_desc->SetStencilPixelFormat(PixelFormat::kS8UInt);
349 
350  ASSERT_TRUE(pipeline_desc.has_value());
351  auto box_pipeline =
352  context->GetPipelineLibrary()->GetPipeline(pipeline_desc).Get();
353  ASSERT_TRUE(box_pipeline);
354  auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
355 
356  VertexBufferBuilder<VS::PerVertexData> vertex_builder;
357  vertex_builder.SetLabel("Box");
358  vertex_builder.AddVertices({
359  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
360  {{800, 100, 0.0}, {1.0, 0.0}}, // 2
361  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
362  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
363  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
364  {{100, 800, 0.0}, {0.0, 1.0}}, // 4
365  });
366  auto vertex_buffer =
367  vertex_builder.CreateVertexBuffer(*context->GetResourceAllocator());
368  ASSERT_TRUE(vertex_buffer);
369 
370  auto bridge = CreateTextureForFixture("bay_bridge.jpg");
371  auto boston = CreateTextureForFixture("boston.jpg");
372  ASSERT_TRUE(bridge && boston);
373  const std::unique_ptr<const Sampler>& sampler =
374  context->GetSamplerLibrary()->GetSampler({});
375  ASSERT_TRUE(sampler);
376 
377  std::shared_ptr<RenderPass> r2t_pass;
378  auto cmd_buffer = context->CreateCommandBuffer();
379  ASSERT_TRUE(cmd_buffer);
380  {
381  ColorAttachment color0;
382  color0.load_action = LoadAction::kClear;
383  color0.store_action = StoreAction::kStore;
384 
385  TextureDescriptor texture_descriptor;
386  ASSERT_NE(pipeline_desc->GetColorAttachmentDescriptor(0u), nullptr);
387  texture_descriptor.format =
388  pipeline_desc->GetColorAttachmentDescriptor(0u)->format;
389  texture_descriptor.storage_mode = StorageMode::kHostVisible;
390  texture_descriptor.size = {400, 400};
391  texture_descriptor.mip_count = 1u;
392  texture_descriptor.usage = TextureUsage::kRenderTarget;
393 
394  color0.texture =
395  context->GetResourceAllocator()->CreateTexture(texture_descriptor);
396 
397  ASSERT_TRUE(color0.IsValid());
398 
399  color0.texture->SetLabel("r2t_target");
400 
401  StencilAttachment stencil0;
402  stencil0.load_action = LoadAction::kClear;
403  stencil0.store_action = StoreAction::kDontCare;
404  TextureDescriptor stencil_texture_desc;
405  stencil_texture_desc.storage_mode = StorageMode::kDeviceTransient;
406  stencil_texture_desc.size = texture_descriptor.size;
407  stencil_texture_desc.format = PixelFormat::kS8UInt;
408  stencil_texture_desc.usage = TextureUsage::kRenderTarget;
409  stencil0.texture =
410  context->GetResourceAllocator()->CreateTexture(stencil_texture_desc);
411 
412  RenderTarget r2t_desc;
413  r2t_desc.SetColorAttachment(color0, 0u);
414  r2t_desc.SetStencilAttachment(stencil0);
415  r2t_pass = cmd_buffer->CreateRenderPass(r2t_desc);
416  ASSERT_TRUE(r2t_pass && r2t_pass->IsValid());
417  }
418 
419  r2t_pass->SetCommandLabel("Box");
420  r2t_pass->SetPipeline(box_pipeline);
421  r2t_pass->SetVertexBuffer(vertex_buffer);
422 
423  FS::FrameInfo frame_info;
424  frame_info.current_time = GetSecondsElapsed();
425  frame_info.cursor_position = GetCursorPosition();
426  frame_info.window_size.x = GetWindowSize().width;
427  frame_info.window_size.y = GetWindowSize().height;
428 
429  FS::BindFrameInfo(*r2t_pass, host_buffer->EmplaceUniform(frame_info));
430  FS::BindContents1(*r2t_pass, boston, sampler);
431  FS::BindContents2(*r2t_pass, bridge, sampler);
432 
433  VS::UniformBuffer uniforms;
434  uniforms.mvp = Matrix::MakeOrthographic(ISize{1024, 768}) *
435  Matrix::MakeTranslation({50.0f, 50.0f, 0.0f});
436  VS::BindUniformBuffer(*r2t_pass, host_buffer->EmplaceUniform(uniforms));
437  ASSERT_TRUE(r2t_pass->Draw().ok());
438  ASSERT_TRUE(r2t_pass->EncodeCommands());
439 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), impeller::HostBuffer::Create(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::CreateVertexBuffer(), impeller::TextureDescriptor::format, impeller::Attachment::IsValid(), impeller::kClear, impeller::kCount1, impeller::kDeviceTransient, impeller::kDontCare, impeller::kHostVisible, impeller::kRenderTarget, impeller::kS8UInt, impeller::kStore, impeller::Attachment::load_action, impeller::Matrix::MakeOrthographic(), impeller::Matrix::MakeTranslation(), impeller::TextureDescriptor::mip_count, impeller::RenderTarget::SetColorAttachment(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::SetLabel(), impeller::RenderTarget::SetStencilAttachment(), impeller::TextureDescriptor::size, impeller::TextureDescriptor::storage_mode, impeller::Attachment::store_action, impeller::Attachment::texture, and impeller::TextureDescriptor::usage.

◆ TEST_P() [421/454]

impeller::testing::TEST_P ( RendererTest  ,
CanSepiaToneThenSwizzleWithSubpasses   
)

Definition at line 1482 of file renderer_unittests.cc.

1482  {
1483  // Define shader types
1484  using TextureVS = TextureVertexShader;
1485  using TextureFS = TextureFragmentShader;
1486 
1487  using SwizzleVS = SepiaVertexShader;
1488  using SwizzleFS = SwizzleFragmentShader;
1489 
1490  using SepiaVS = SepiaVertexShader;
1491  using SepiaFS = SepiaFragmentShader;
1492 
1493  auto context = GetContext();
1494  ASSERT_TRUE(context);
1495 
1496  if (!context->GetCapabilities()->SupportsFramebufferFetch()) {
1497  GTEST_SKIP() << "This test uses framebuffer fetch and the backend doesn't "
1498  "support it.";
1499  return;
1500  }
1501 
1502  // Create pipelines.
1503  auto texture_pipeline = CreateDefaultPipeline<TextureVS, TextureFS>(context);
1504  auto swizzle_pipeline = CreateDefaultPipeline<SwizzleVS, SwizzleFS>(context);
1505  auto sepia_pipeline = CreateDefaultPipeline<SepiaVS, SepiaFS>(context);
1506 
1507  ASSERT_TRUE(texture_pipeline);
1508  ASSERT_TRUE(swizzle_pipeline);
1509  ASSERT_TRUE(sepia_pipeline);
1510 
1511  // Vertex buffer builders.
1512  VertexBufferBuilder<TextureVS::PerVertexData> texture_vtx_builder;
1513  texture_vtx_builder.AddVertices({
1514  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
1515  {{800, 100, 0.0}, {1.0, 0.0}}, // 2
1516  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
1517  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
1518  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
1519  {{100, 800, 0.0}, {0.0, 1.0}}, // 4
1520  });
1521 
1522  VertexBufferBuilder<SepiaVS::PerVertexData> sepia_vtx_builder;
1523  sepia_vtx_builder.AddVertices({
1524  {{100, 100, 0.0}}, // 1
1525  {{800, 100, 0.0}}, // 2
1526  {{800, 800, 0.0}}, // 3
1527  {{100, 100, 0.0}}, // 1
1528  {{800, 800, 0.0}}, // 3
1529  {{100, 800, 0.0}}, // 4
1530  });
1531 
1532  auto boston = CreateTextureForFixture("boston.jpg");
1533  ASSERT_TRUE(boston);
1534 
1535  const auto& sampler = context->GetSamplerLibrary()->GetSampler({});
1536  ASSERT_TRUE(sampler);
1537 
1538  SinglePassCallback callback = [&](RenderPass& pass) {
1539  auto buffer = HostBuffer::Create(context->GetResourceAllocator());
1540 
1541  // Draw the texture.
1542  {
1543  pass.SetPipeline(texture_pipeline);
1544  pass.SetVertexBuffer(texture_vtx_builder.CreateVertexBuffer(
1545  *context->GetResourceAllocator()));
1546  TextureVS::UniformBuffer uniforms;
1547  uniforms.mvp = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) *
1548  Matrix::MakeScale(GetContentScale());
1549  TextureVS::BindUniformBuffer(pass, buffer->EmplaceUniform(uniforms));
1550  TextureFS::BindTextureContents(pass, boston, sampler);
1551  if (!pass.Draw().ok()) {
1552  return false;
1553  }
1554  }
1555 
1556  // Draw the sepia toner.
1557  {
1558  pass.SetPipeline(sepia_pipeline);
1559  pass.SetVertexBuffer(sepia_vtx_builder.CreateVertexBuffer(
1560  *context->GetResourceAllocator()));
1561  SepiaVS::UniformBuffer uniforms;
1562  uniforms.mvp = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) *
1563  Matrix::MakeScale(GetContentScale());
1564  SepiaVS::BindUniformBuffer(pass, buffer->EmplaceUniform(uniforms));
1565  if (!pass.Draw().ok()) {
1566  return false;
1567  }
1568  }
1569 
1570  // Draw the swizzle.
1571  {
1572  pass.SetPipeline(swizzle_pipeline);
1573  pass.SetVertexBuffer(sepia_vtx_builder.CreateVertexBuffer(
1574  *context->GetResourceAllocator()));
1575  SwizzleVS::UniformBuffer uniforms;
1576  uniforms.mvp = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) *
1577  Matrix::MakeScale(GetContentScale());
1578  SwizzleVS::BindUniformBuffer(pass, buffer->EmplaceUniform(uniforms));
1579  if (!pass.Draw().ok()) {
1580  return false;
1581  }
1582  }
1583 
1584  return true;
1585  };
1586  OpenPlaygroundHere(callback);
1587 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), impeller::HostBuffer::Create(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::CreateVertexBuffer(), impeller::Matrix::MakeOrthographic(), and impeller::Matrix::MakeScale().

◆ TEST_P() [422/454]

impeller::testing::TEST_P ( RendererTest  ,
CanSepiaToneWithSubpasses   
)

Definition at line 1394 of file renderer_unittests.cc.

1394  {
1395  // Define shader types
1396  using TextureVS = TextureVertexShader;
1397  using TextureFS = TextureFragmentShader;
1398 
1399  using SepiaVS = SepiaVertexShader;
1400  using SepiaFS = SepiaFragmentShader;
1401 
1402  auto context = GetContext();
1403  ASSERT_TRUE(context);
1404 
1405  if (!context->GetCapabilities()->SupportsFramebufferFetch()) {
1406  GTEST_SKIP() << "This test uses framebuffer fetch and the backend doesn't "
1407  "support it.";
1408  return;
1409  }
1410 
1411  // Create pipelines.
1412  auto texture_pipeline = CreateDefaultPipeline<TextureVS, TextureFS>(context);
1413  auto sepia_pipeline = CreateDefaultPipeline<SepiaVS, SepiaFS>(context);
1414 
1415  ASSERT_TRUE(texture_pipeline);
1416  ASSERT_TRUE(sepia_pipeline);
1417 
1418  // Vertex buffer builders.
1419  VertexBufferBuilder<TextureVS::PerVertexData> texture_vtx_builder;
1420  texture_vtx_builder.AddVertices({
1421  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
1422  {{800, 100, 0.0}, {1.0, 0.0}}, // 2
1423  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
1424  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
1425  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
1426  {{100, 800, 0.0}, {0.0, 1.0}}, // 4
1427  });
1428 
1429  VertexBufferBuilder<SepiaVS::PerVertexData> sepia_vtx_builder;
1430  sepia_vtx_builder.AddVertices({
1431  {{100, 100, 0.0}}, // 1
1432  {{800, 100, 0.0}}, // 2
1433  {{800, 800, 0.0}}, // 3
1434  {{100, 100, 0.0}}, // 1
1435  {{800, 800, 0.0}}, // 3
1436  {{100, 800, 0.0}}, // 4
1437  });
1438 
1439  auto boston = CreateTextureForFixture("boston.jpg");
1440  ASSERT_TRUE(boston);
1441 
1442  const auto& sampler = context->GetSamplerLibrary()->GetSampler({});
1443  ASSERT_TRUE(sampler);
1444 
1445  SinglePassCallback callback = [&](RenderPass& pass) {
1446  auto buffer = HostBuffer::Create(context->GetResourceAllocator());
1447 
1448  // Draw the texture.
1449  {
1450  pass.SetPipeline(texture_pipeline);
1451  pass.SetVertexBuffer(texture_vtx_builder.CreateVertexBuffer(
1452  *context->GetResourceAllocator()));
1453  TextureVS::UniformBuffer uniforms;
1454  uniforms.mvp = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) *
1455  Matrix::MakeScale(GetContentScale());
1456  TextureVS::BindUniformBuffer(pass, buffer->EmplaceUniform(uniforms));
1457  TextureFS::BindTextureContents(pass, boston, sampler);
1458  if (!pass.Draw().ok()) {
1459  return false;
1460  }
1461  }
1462 
1463  // Draw the sepia toner.
1464  {
1465  pass.SetPipeline(sepia_pipeline);
1466  pass.SetVertexBuffer(sepia_vtx_builder.CreateVertexBuffer(
1467  *context->GetResourceAllocator()));
1468  SepiaVS::UniformBuffer uniforms;
1469  uniforms.mvp = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) *
1470  Matrix::MakeScale(GetContentScale());
1471  SepiaVS::BindUniformBuffer(pass, buffer->EmplaceUniform(uniforms));
1472  if (!pass.Draw().ok()) {
1473  return false;
1474  }
1475  }
1476 
1477  return true;
1478  };
1479  OpenPlaygroundHere(callback);
1480 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), impeller::HostBuffer::Create(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::CreateVertexBuffer(), impeller::Matrix::MakeOrthographic(), and impeller::Matrix::MakeScale().

◆ TEST_P() [423/454]

impeller::testing::TEST_P ( RendererTest  ,
DefaultIndexBehavior   
)

Definition at line 1111 of file renderer_unittests.cc.

1111  {
1112  using VS = BoxFadeVertexShader;
1113 
1114  // Do not create any index buffer if no indices were provided.
1115  VertexBufferBuilder<VS::PerVertexData> vertex_builder;
1116  ASSERT_EQ(vertex_builder.GetIndexType(), IndexType::kNone);
1117 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::GetIndexType(), and impeller::kNone.

◆ TEST_P() [424/454]

impeller::testing::TEST_P ( RendererTest  ,
DefaultIndexSize   
)

Definition at line 1101 of file renderer_unittests.cc.

1101  {
1102  using VS = BoxFadeVertexShader;
1103 
1104  // Default to 16bit index buffer size, as this is a reasonable default and
1105  // supported on all backends without extensions.
1106  VertexBufferBuilder<VS::PerVertexData> vertex_builder;
1107  vertex_builder.AppendIndex(0u);
1108  ASSERT_EQ(vertex_builder.GetIndexType(), IndexType::k16bit);
1109 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AppendIndex(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::GetIndexType(), and impeller::k16bit.

◆ TEST_P() [425/454]

impeller::testing::TEST_P ( RendererTest  ,
InactiveUniforms   
)

Definition at line 1054 of file renderer_unittests.cc.

1054  {
1055  using VS = InactiveUniformsVertexShader;
1056  using FS = InactiveUniformsFragmentShader;
1057 
1058  auto context = GetContext();
1059  auto pipeline_descriptor =
1060  PipelineBuilder<VS, FS>::MakeDefaultPipelineDescriptor(*context);
1061  ASSERT_TRUE(pipeline_descriptor.has_value());
1062  pipeline_descriptor->SetSampleCount(SampleCount::kCount4);
1063  pipeline_descriptor->SetStencilAttachmentDescriptors(std::nullopt);
1064  auto pipeline =
1065  context->GetPipelineLibrary()->GetPipeline(pipeline_descriptor).Get();
1066  ASSERT_TRUE(pipeline && pipeline->IsValid());
1067 
1068  auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
1069  SinglePassCallback callback = [&](RenderPass& pass) {
1070  auto size = pass.GetRenderTargetSize();
1071 
1072  pass.SetPipeline(pipeline);
1073  pass.SetCommandLabel("Inactive Uniform");
1074 
1075  VertexBufferBuilder<VS::PerVertexData> builder;
1076  builder.AddVertices({{Point()},
1077  {Point(0, size.height)},
1078  {Point(size.width, 0)},
1079  {Point(size.width, 0)},
1080  {Point(0, size.height)},
1081  {Point(size.width, size.height)}});
1082  pass.SetVertexBuffer(builder.CreateVertexBuffer(*host_buffer));
1083 
1084  VS::FrameInfo frame_info;
1085  EXPECT_EQ(pass.GetOrthographicTransform(), Matrix::MakeOrthographic(size));
1086  frame_info.mvp =
1087  pass.GetOrthographicTransform() * Matrix::MakeScale(GetContentScale());
1088  VS::BindFrameInfo(pass, host_buffer->EmplaceUniform(frame_info));
1089 
1090  FS::FragInfo fs_uniform = {.unused_color = Color::Red(),
1091  .color = Color::Green()};
1092  FS::BindFragInfo(pass, host_buffer->EmplaceUniform(fs_uniform));
1093 
1094  pass.Draw().ok();
1095  host_buffer->Reset();
1096  return true;
1097  };
1098  OpenPlaygroundHere(callback);
1099 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), impeller::HostBuffer::Create(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::CreateVertexBuffer(), impeller::Color::Green(), impeller::kCount4, impeller::PipelineBuilder< VertexShader_, FragmentShader_ >::MakeDefaultPipelineDescriptor(), impeller::Matrix::MakeOrthographic(), impeller::Matrix::MakeScale(), and impeller::Color::Red().

◆ TEST_P() [426/454]

impeller::testing::TEST_P ( RendererTest  ,
Planet   
)

Definition at line 931 of file renderer_unittests.cc.

931  {
932  using VS = PlanetVertexShader;
933  using FS = PlanetFragmentShader;
934 
935  auto context = GetContext();
936  auto pipeline_descriptor =
937  PipelineBuilder<VS, FS>::MakeDefaultPipelineDescriptor(*context);
938  ASSERT_TRUE(pipeline_descriptor.has_value());
939  pipeline_descriptor->SetSampleCount(SampleCount::kCount4);
940  pipeline_descriptor->SetStencilAttachmentDescriptors(std::nullopt);
941  auto pipeline =
942  context->GetPipelineLibrary()->GetPipeline(pipeline_descriptor).Get();
943  ASSERT_TRUE(pipeline && pipeline->IsValid());
944 
945  auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
946 
947  SinglePassCallback callback = [&](RenderPass& pass) {
948  static Scalar speed = 0.1;
949  static Scalar planet_size = 550.0;
950  static bool show_normals = false;
951  static bool show_noise = false;
952  static Scalar seed_value = 42.0;
953 
954  auto size = pass.GetRenderTargetSize();
955 
956  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
957  ImGui::SliderFloat("Speed", &speed, 0.0, 10.0);
958  ImGui::SliderFloat("Planet Size", &planet_size, 0.1, 1000);
959  ImGui::Checkbox("Show Normals", &show_normals);
960  ImGui::Checkbox("Show Noise", &show_noise);
961  ImGui::InputFloat("Seed Value", &seed_value);
962  ImGui::End();
963 
964  pass.SetPipeline(pipeline);
965  pass.SetCommandLabel("Planet scene");
966  VertexBufferBuilder<VS::PerVertexData> builder;
967  builder.AddVertices({{Point()},
968  {Point(0, size.height)},
969  {Point(size.width, 0)},
970  {Point(size.width, 0)},
971  {Point(0, size.height)},
972  {Point(size.width, size.height)}});
973  pass.SetVertexBuffer(builder.CreateVertexBuffer(*host_buffer));
974 
975  VS::FrameInfo frame_info;
976  EXPECT_EQ(pass.GetOrthographicTransform(), Matrix::MakeOrthographic(size));
977  frame_info.mvp = pass.GetOrthographicTransform();
978  VS::BindFrameInfo(pass, host_buffer->EmplaceUniform(frame_info));
979 
980  FS::FragInfo fs_uniform;
981  fs_uniform.resolution = Point(size);
982  fs_uniform.time = GetSecondsElapsed();
983  fs_uniform.speed = speed;
984  fs_uniform.planet_size = planet_size;
985  fs_uniform.show_normals = show_normals ? 1.0 : 0.0;
986  fs_uniform.show_noise = show_noise ? 1.0 : 0.0;
987  fs_uniform.seed_value = seed_value;
988  FS::BindFragInfo(pass, host_buffer->EmplaceUniform(fs_uniform));
989 
990  pass.Draw().ok();
991  host_buffer->Reset();
992  return true;
993  };
994  OpenPlaygroundHere(callback);
995 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), impeller::HostBuffer::Create(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::CreateVertexBuffer(), impeller::kCount4, impeller::PipelineBuilder< VertexShader_, FragmentShader_ >::MakeDefaultPipelineDescriptor(), and impeller::Matrix::MakeOrthographic().

◆ TEST_P() [427/454]

impeller::testing::TEST_P ( RendererTest  ,
RenderTargetCreateOffscreenMSAASetsDefaultDepthStencilFormat   
)

Definition at line 1361 of file renderer_unittests.cc.

1362  {
1363  auto context = GetContext();
1364  auto render_target_cache = std::make_shared<RenderTargetAllocator>(
1365  GetContext()->GetResourceAllocator());
1366 
1367  RenderTarget render_target = render_target_cache->CreateOffscreenMSAA(
1368  *context, {100, 100}, /*mip_count=*/1);
1369  EXPECT_EQ(render_target.GetDepthAttachment()
1370  ->texture->GetTextureDescriptor()
1371  .format,
1372  GetContext()->GetCapabilities()->GetDefaultDepthStencilFormat());
1373 }

References impeller::RenderTarget::GetDepthAttachment().

◆ TEST_P() [428/454]

impeller::testing::TEST_P ( RendererTest  ,
StencilMask   
)

Definition at line 1189 of file renderer_unittests.cc.

1189  {
1190  using VS = BoxFadeVertexShader;
1191  using FS = BoxFadeFragmentShader;
1192  auto context = GetContext();
1193  ASSERT_TRUE(context);
1194  using BoxFadePipelineBuilder = PipelineBuilder<VS, FS>;
1195  auto desc = BoxFadePipelineBuilder::MakeDefaultPipelineDescriptor(*context);
1196  ASSERT_TRUE(desc.has_value());
1197 
1198  // Vertex buffer.
1199  VertexBufferBuilder<VS::PerVertexData> vertex_builder;
1200  vertex_builder.SetLabel("Box");
1201  vertex_builder.AddVertices({
1202  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
1203  {{800, 100, 0.0}, {1.0, 0.0}}, // 2
1204  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
1205  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
1206  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
1207  {{100, 800, 0.0}, {0.0, 1.0}}, // 4
1208  });
1209  auto vertex_buffer =
1210  vertex_builder.CreateVertexBuffer(*context->GetResourceAllocator());
1211  ASSERT_TRUE(vertex_buffer);
1212 
1213  desc->SetSampleCount(SampleCount::kCount4);
1214  desc->SetStencilAttachmentDescriptors(std::nullopt);
1215 
1216  auto bridge = CreateTextureForFixture("bay_bridge.jpg");
1217  auto boston = CreateTextureForFixture("boston.jpg");
1218  ASSERT_TRUE(bridge && boston);
1219  const std::unique_ptr<const Sampler>& sampler =
1220  context->GetSamplerLibrary()->GetSampler({});
1221  ASSERT_TRUE(sampler);
1222 
1223  static bool mirror = false;
1224  static int stencil_reference_write = 0xFF;
1225  static int stencil_reference_read = 0x1;
1226  std::vector<uint8_t> stencil_contents;
1227  static int last_stencil_contents_reference_value = 0;
1228  static int current_front_compare =
1229  CompareFunctionUI().IndexOf(CompareFunction::kLessEqual);
1230  static int current_back_compare =
1231  CompareFunctionUI().IndexOf(CompareFunction::kLessEqual);
1232 
1233  auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
1234  Playground::RenderCallback callback = [&](RenderTarget& render_target) {
1235  auto buffer = context->CreateCommandBuffer();
1236  if (!buffer) {
1237  return false;
1238  }
1239  buffer->SetLabel("Playground Command Buffer");
1240 
1241  {
1242  // Configure the stencil attachment for the test.
1243  RenderTarget::AttachmentConfig stencil_config;
1244  stencil_config.load_action = LoadAction::kLoad;
1245  stencil_config.store_action = StoreAction::kDontCare;
1246  stencil_config.storage_mode = StorageMode::kHostVisible;
1247  render_target.SetupDepthStencilAttachments(
1248  *context, *context->GetResourceAllocator(),
1249  render_target.GetRenderTargetSize(), true, "stencil", stencil_config);
1250  // Fill the stencil buffer with an checkerboard pattern.
1251  const auto target_width = render_target.GetRenderTargetSize().width;
1252  const auto target_height = render_target.GetRenderTargetSize().height;
1253  const size_t target_size = target_width * target_height;
1254  if (stencil_contents.size() != target_size ||
1255  last_stencil_contents_reference_value != stencil_reference_write) {
1256  stencil_contents.resize(target_size);
1257  last_stencil_contents_reference_value = stencil_reference_write;
1258  for (int y = 0; y < target_height; y++) {
1259  for (int x = 0; x < target_width; x++) {
1260  const auto index = y * target_width + x;
1261  const auto kCheckSize = 64;
1262  const auto value =
1263  (((y / kCheckSize) + (x / kCheckSize)) % 2 == 0) *
1264  stencil_reference_write;
1265  stencil_contents[index] = value;
1266  }
1267  }
1268  }
1269  if (!render_target.GetStencilAttachment()->texture->SetContents(
1270  stencil_contents.data(), stencil_contents.size(), 0, false)) {
1271  VALIDATION_LOG << "Could not upload stencil contents to device memory";
1272  return false;
1273  }
1274  auto pass = buffer->CreateRenderPass(render_target);
1275  if (!pass) {
1276  return false;
1277  }
1278  pass->SetLabel("Stencil Buffer");
1279  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
1280  ImGui::SliderInt("Stencil Write Value", &stencil_reference_write, 0,
1281  0xFF);
1282  ImGui::SliderInt("Stencil Compare Value", &stencil_reference_read, 0,
1283  0xFF);
1284  ImGui::Checkbox("Back face mode", &mirror);
1285  ImGui::ListBox("Front face compare function", &current_front_compare,
1286  CompareFunctionUI().labels(), CompareFunctionUI().size());
1287  ImGui::ListBox("Back face compare function", &current_back_compare,
1288  CompareFunctionUI().labels(), CompareFunctionUI().size());
1289  ImGui::End();
1290 
1291  StencilAttachmentDescriptor front;
1292  front.stencil_compare =
1293  CompareFunctionUI().FunctionOf(current_front_compare);
1294  StencilAttachmentDescriptor back;
1295  back.stencil_compare =
1296  CompareFunctionUI().FunctionOf(current_back_compare);
1297  desc->SetStencilAttachmentDescriptors(front, back);
1298  auto pipeline = context->GetPipelineLibrary()->GetPipeline(desc).Get();
1299 
1300  assert(pipeline && pipeline->IsValid());
1301 
1302  pass->SetCommandLabel("Box");
1303  pass->SetPipeline(pipeline);
1304  pass->SetStencilReference(stencil_reference_read);
1305  pass->SetVertexBuffer(vertex_buffer);
1306 
1307  VS::UniformBuffer uniforms;
1308  EXPECT_EQ(pass->GetOrthographicTransform(),
1309  Matrix::MakeOrthographic(pass->GetRenderTargetSize()));
1310  uniforms.mvp = pass->GetOrthographicTransform() *
1311  Matrix::MakeScale(GetContentScale());
1312  if (mirror) {
1313  uniforms.mvp = Matrix::MakeScale(Vector2(-1, 1)) * uniforms.mvp;
1314  }
1315  VS::BindUniformBuffer(*pass, host_buffer->EmplaceUniform(uniforms));
1316 
1317  FS::FrameInfo frame_info;
1318  frame_info.current_time = GetSecondsElapsed();
1319  frame_info.cursor_position = GetCursorPosition();
1320  frame_info.window_size.x = GetWindowSize().width;
1321  frame_info.window_size.y = GetWindowSize().height;
1322 
1323  FS::BindFrameInfo(*pass, host_buffer->EmplaceUniform(frame_info));
1324  FS::BindContents1(*pass, boston, sampler);
1325  FS::BindContents2(*pass, bridge, sampler);
1326  if (!pass->Draw().ok()) {
1327  return false;
1328  }
1329  pass->EncodeCommands();
1330  }
1331 
1332  if (!context->GetCommandQueue()->Submit({buffer}).ok()) {
1333  return false;
1334  }
1335  host_buffer->Reset();
1336  return true;
1337  };
1338  OpenPlaygroundHere(callback);
1339 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), CompareFunctionUI(), impeller::HostBuffer::Create(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::CreateVertexBuffer(), impeller::testing::CompareFunctionUIData::FunctionOf(), impeller::testing::CompareFunctionUIData::IndexOf(), impeller::kCount4, impeller::kDontCare, impeller::kHostVisible, impeller::kLessEqual, impeller::kLoad, impeller::RenderTarget::AttachmentConfig::load_action, impeller::Matrix::MakeOrthographic(), impeller::Matrix::MakeScale(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::SetLabel(), impeller::StencilAttachmentDescriptor::stencil_compare, impeller::RenderTarget::AttachmentConfig::storage_mode, impeller::RenderTarget::AttachmentConfig::store_action, and VALIDATION_LOG.

◆ TEST_P() [429/454]

impeller::testing::TEST_P ( RendererTest  ,
TheImpeller   
)

Definition at line 869 of file renderer_unittests.cc.

869  {
870  using VS = ImpellerVertexShader;
871  using FS = ImpellerFragmentShader;
872 
873  auto context = GetContext();
874  auto pipeline_descriptor =
875  PipelineBuilder<VS, FS>::MakeDefaultPipelineDescriptor(*context);
876  ASSERT_TRUE(pipeline_descriptor.has_value());
877  pipeline_descriptor->SetSampleCount(SampleCount::kCount4);
878  pipeline_descriptor->SetStencilAttachmentDescriptors(std::nullopt);
879  auto pipeline =
880  context->GetPipelineLibrary()->GetPipeline(pipeline_descriptor).Get();
881  ASSERT_TRUE(pipeline && pipeline->IsValid());
882 
883  auto blue_noise = CreateTextureForFixture("blue_noise.png");
884  SamplerDescriptor noise_sampler_desc;
885  noise_sampler_desc.width_address_mode = SamplerAddressMode::kRepeat;
886  noise_sampler_desc.height_address_mode = SamplerAddressMode::kRepeat;
887  const std::unique_ptr<const Sampler>& noise_sampler =
888  context->GetSamplerLibrary()->GetSampler(noise_sampler_desc);
889 
890  auto cube_map = CreateTextureCubeForFixture(
891  {"table_mountain_px.png", "table_mountain_nx.png",
892  "table_mountain_py.png", "table_mountain_ny.png",
893  "table_mountain_pz.png", "table_mountain_nz.png"});
894  const std::unique_ptr<const Sampler>& cube_map_sampler =
895  context->GetSamplerLibrary()->GetSampler({});
896  auto host_buffer = HostBuffer::Create(context->GetResourceAllocator());
897 
898  SinglePassCallback callback = [&](RenderPass& pass) {
899  auto size = pass.GetRenderTargetSize();
900 
901  pass.SetPipeline(pipeline);
902  pass.SetCommandLabel("Impeller SDF scene");
903  VertexBufferBuilder<VS::PerVertexData> builder;
904  builder.AddVertices({{Point()},
905  {Point(0, size.height)},
906  {Point(size.width, 0)},
907  {Point(size.width, 0)},
908  {Point(0, size.height)},
909  {Point(size.width, size.height)}});
910  pass.SetVertexBuffer(builder.CreateVertexBuffer(*host_buffer));
911 
912  VS::FrameInfo frame_info;
913  EXPECT_EQ(pass.GetOrthographicTransform(), Matrix::MakeOrthographic(size));
914  frame_info.mvp = pass.GetOrthographicTransform();
915  VS::BindFrameInfo(pass, host_buffer->EmplaceUniform(frame_info));
916 
917  FS::FragInfo fs_uniform;
918  fs_uniform.texture_size = Point(size);
919  fs_uniform.time = GetSecondsElapsed();
920  FS::BindFragInfo(pass, host_buffer->EmplaceUniform(fs_uniform));
921  FS::BindBlueNoise(pass, blue_noise, noise_sampler);
922  FS::BindCubeMap(pass, cube_map, cube_map_sampler);
923 
924  pass.Draw().ok();
925  host_buffer->Reset();
926  return true;
927  };
928  OpenPlaygroundHere(callback);
929 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), impeller::HostBuffer::Create(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::CreateVertexBuffer(), impeller::SamplerDescriptor::height_address_mode, impeller::kCount4, impeller::kRepeat, impeller::PipelineBuilder< VertexShader_, FragmentShader_ >::MakeDefaultPipelineDescriptor(), impeller::Matrix::MakeOrthographic(), and impeller::SamplerDescriptor::width_address_mode.

◆ TEST_P() [430/454]

impeller::testing::TEST_P ( RendererTest  ,
VertexBufferBuilder   
)

Definition at line 1119 of file renderer_unittests.cc.

1119  {
1120  // Does not create index buffer if one is provided.
1121  using VS = BoxFadeVertexShader;
1122  VertexBufferBuilder<VS::PerVertexData> vertex_builder;
1123  vertex_builder.SetLabel("Box");
1124  vertex_builder.AddVertices({
1125  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
1126  {{800, 100, 0.0}, {1.0, 0.0}}, // 2
1127  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
1128  {{100, 800, 0.0}, {0.0, 1.0}}, // 4
1129  });
1130  vertex_builder.AppendIndex(0);
1131  vertex_builder.AppendIndex(1);
1132  vertex_builder.AppendIndex(2);
1133  vertex_builder.AppendIndex(1);
1134  vertex_builder.AppendIndex(2);
1135  vertex_builder.AppendIndex(3);
1136 
1137  ASSERT_EQ(vertex_builder.GetIndexCount(), 6u);
1138  ASSERT_EQ(vertex_builder.GetVertexCount(), 4u);
1139 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AppendIndex(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::GetIndexCount(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::GetVertexCount(), and impeller::VertexBufferBuilder< VertexType_, IndexType_ >::SetLabel().

◆ TEST_P() [431/454]

impeller::testing::TEST_P ( RenderTargetCacheTest  ,
CachedTextureGetsNewAttachmentConfig   
)

Definition at line 90 of file render_target_cache_unittests.cc.

90  {
91  auto render_target_cache =
92  RenderTargetCache(GetContext()->GetResourceAllocator());
93 
94  render_target_cache.Start();
95  RenderTarget::AttachmentConfig color_attachment_config =
96  RenderTarget::kDefaultColorAttachmentConfig;
97  RenderTarget target1 = render_target_cache.CreateOffscreen(
98  *GetContext(), {100, 100}, 1, "Offscreen1", color_attachment_config);
99  render_target_cache.End();
100 
101  render_target_cache.Start();
102  color_attachment_config.clear_color = Color::Red();
103  RenderTarget target2 = render_target_cache.CreateOffscreen(
104  *GetContext(), {100, 100}, 1, "Offscreen2", color_attachment_config);
105  render_target_cache.End();
106 
107  auto color1 = target1.GetColorAttachments().find(0)->second;
108  auto color2 = target2.GetColorAttachments().find(0)->second;
109  // The second color attachment should reuse the first attachment's texture
110  // but with attributes from the second AttachmentConfig.
111  EXPECT_EQ(color2.texture, color1.texture);
112  EXPECT_EQ(color2.clear_color, Color::Red());
113 }

References impeller::RenderTarget::AttachmentConfig::clear_color, impeller::RenderTarget::GetColorAttachments(), impeller::RenderTarget::kDefaultColorAttachmentConfig, and impeller::Color::Red().

◆ TEST_P() [432/454]

impeller::testing::TEST_P ( RenderTargetCacheTest  ,
CachesUsedTexturesAcrossFrames   
)

Definition at line 51 of file render_target_cache_unittests.cc.

51  {
52  auto render_target_cache =
53  RenderTargetCache(GetContext()->GetResourceAllocator());
54 
55  render_target_cache.Start();
56  // Create two render targets of the same exact size/shape. Both should be
57  // marked as used this frame, so the cached data set will contain two.
58  render_target_cache.CreateOffscreen(*GetContext(), {100, 100}, 1);
59  render_target_cache.CreateOffscreen(*GetContext(), {100, 100}, 1);
60 
61  EXPECT_EQ(render_target_cache.CachedTextureCount(), 2u);
62 
63  render_target_cache.End();
64  render_target_cache.Start();
65 
66  // Next frame, only create one texture. The set will still contain two,
67  // but one will be removed at the end of the frame.
68  render_target_cache.CreateOffscreen(*GetContext(), {100, 100}, 1);
69  EXPECT_EQ(render_target_cache.CachedTextureCount(), 2u);
70 
71  render_target_cache.End();
72  EXPECT_EQ(render_target_cache.CachedTextureCount(), 1u);
73 }

◆ TEST_P() [433/454]

impeller::testing::TEST_P ( RenderTargetCacheTest  ,
CreateWithEmptySize   
)

Definition at line 115 of file render_target_cache_unittests.cc.

115  {
116  auto render_target_cache =
117  RenderTargetCache(GetContext()->GetResourceAllocator());
118 
119  render_target_cache.Start();
120  RenderTarget empty_target =
121  render_target_cache.CreateOffscreen(*GetContext(), {100, 0}, 1);
122  RenderTarget empty_target_msaa =
123  render_target_cache.CreateOffscreenMSAA(*GetContext(), {0, 0}, 1);
124  render_target_cache.End();
125 
126  {
127  ScopedValidationDisable disable_validation;
128  EXPECT_FALSE(empty_target.IsValid());
129  EXPECT_FALSE(empty_target_msaa.IsValid());
130  }
131 }

References impeller::RenderTarget::IsValid().

◆ TEST_P() [434/454]

impeller::testing::TEST_P ( RenderTargetCacheTest  ,
DoesNotPersistFailedAllocations   
)

Definition at line 75 of file render_target_cache_unittests.cc.

75  {
76  ScopedValidationDisable disable;
77  auto allocator = std::make_shared<TestAllocator>();
78  auto render_target_cache = RenderTargetCache(allocator);
79 
80  render_target_cache.Start();
81  allocator->should_fail = true;
82 
83  auto render_target =
84  render_target_cache.CreateOffscreen(*GetContext(), {100, 100}, 1);
85 
86  EXPECT_FALSE(render_target.IsValid());
87  EXPECT_EQ(render_target_cache.CachedTextureCount(), 0u);
88 }

◆ TEST_P() [435/454]

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() [436/454]

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() [437/454]

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() [438/454]

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() [439/454]

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() [440/454]

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 }

References impeller::RuntimeStage::DecodeRuntimeStages(), impeller::kFragment, impeller::PlaygroundBackendToRuntimeStageBackend(), and impeller::ToShaderStage().

◆ TEST_P() [441/454]

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 }

References impeller::CreateMappingFromAllocation(), impeller::RuntimeStage::DecodeRuntimeStages(), and impeller::PlaygroundBackendToRuntimeStageBackend().

◆ TEST_P() [442/454]

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() [443/454]

impeller::testing::TEST_P ( TypographerTest  ,
CanConvertTextBlob   
)

Definition at line 65 of file typographer_unittests.cc.

65  {
66  SkFont font = flutter::testing::CreateTestFontOfSize(12);
67  auto blob = SkTextBlob::MakeFromString(
68  "the quick brown fox jumped over the lazy dog.", font);
69  ASSERT_TRUE(blob);
70  auto frame = MakeTextFrameFromTextBlobSkia(blob);
71  ASSERT_EQ(frame->GetRunCount(), 1u);
72  for (const auto& run : frame->GetRuns()) {
73  ASSERT_TRUE(run.IsValid());
74  ASSERT_EQ(run.GetGlyphCount(), 45u);
75  }
76 }

References impeller::MakeTextFrameFromTextBlobSkia().

◆ TEST_P() [444/454]

impeller::testing::TEST_P ( TypographerTest  ,
CanCreateGlyphAtlas   
)

Definition at line 83 of file typographer_unittests.cc.

83  {
84  auto context = TypographerContextSkia::Make();
85  auto atlas_context =
86  context->CreateGlyphAtlasContext(GlyphAtlas::Type::kAlphaBitmap);
87  auto host_buffer = HostBuffer::Create(GetContext()->GetResourceAllocator());
88  ASSERT_TRUE(context && context->IsValid());
89  SkFont sk_font = flutter::testing::CreateTestFontOfSize(12);
90  auto blob = SkTextBlob::MakeFromString("hello", sk_font);
91  ASSERT_TRUE(blob);
92  auto atlas =
93  CreateGlyphAtlas(*GetContext(), context.get(), *host_buffer,
94  GlyphAtlas::Type::kAlphaBitmap, 1.0f, atlas_context,
96  ASSERT_NE(atlas, nullptr);
97  ASSERT_NE(atlas->GetTexture(), nullptr);
98  ASSERT_EQ(atlas->GetType(), GlyphAtlas::Type::kAlphaBitmap);
99  ASSERT_EQ(atlas->GetGlyphCount(), 4llu);
100 
101  std::optional<impeller::ScaledFont> first_scaled_font;
102  std::optional<impeller::SubpixelGlyph> first_glyph;
103  Rect first_rect;
104  atlas->IterateGlyphs([&](const ScaledFont& scaled_font,
105  const SubpixelGlyph& glyph,
106  const Rect& rect) -> bool {
107  first_scaled_font = scaled_font;
108  first_glyph = glyph;
109  first_rect = rect;
110  return false;
111  });
112 
113  ASSERT_TRUE(first_scaled_font.has_value());
114  ASSERT_TRUE(atlas
115  ->FindFontGlyphBounds(
116  {first_scaled_font.value(), first_glyph.value()})
117  .has_value());
118 }

References impeller::HostBuffer::Create(), CreateGlyphAtlas(), impeller::GlyphAtlas::kAlphaBitmap, impeller::TypographerContextSkia::Make(), and impeller::MakeTextFrameFromTextBlobSkia().

◆ TEST_P() [445/454]

impeller::testing::TEST_P ( TypographerTest  ,
CanCreateRenderContext   
)

Definition at line 78 of file typographer_unittests.cc.

78  {
79  auto context = TypographerContextSkia::Make();
80  ASSERT_TRUE(context && context->IsValid());
81 }

References impeller::TypographerContextSkia::Make().

◆ TEST_P() [446/454]

impeller::testing::TEST_P ( TypographerTest  ,
GlyphAtlasIsRecycledIfUnchanged   
)

Definition at line 179 of file typographer_unittests.cc.

179  {
180  auto context = TypographerContextSkia::Make();
181  auto atlas_context =
182  context->CreateGlyphAtlasContext(GlyphAtlas::Type::kAlphaBitmap);
183  auto host_buffer = HostBuffer::Create(GetContext()->GetResourceAllocator());
184  ASSERT_TRUE(context && context->IsValid());
185  SkFont sk_font = flutter::testing::CreateTestFontOfSize(12);
186  auto blob = SkTextBlob::MakeFromString("spooky skellingtons", sk_font);
187  ASSERT_TRUE(blob);
188  auto atlas =
189  CreateGlyphAtlas(*GetContext(), context.get(), *host_buffer,
190  GlyphAtlas::Type::kAlphaBitmap, 1.0f, atlas_context,
192  ASSERT_NE(atlas, nullptr);
193  ASSERT_NE(atlas->GetTexture(), nullptr);
194  ASSERT_EQ(atlas, atlas_context->GetGlyphAtlas());
195 
196  // now attempt to re-create an atlas with the same text blob.
197 
198  auto next_atlas =
199  CreateGlyphAtlas(*GetContext(), context.get(), *host_buffer,
200  GlyphAtlas::Type::kAlphaBitmap, 1.0f, atlas_context,
202  ASSERT_EQ(atlas, next_atlas);
203  ASSERT_EQ(atlas_context->GetGlyphAtlas(), atlas);
204 }

References impeller::HostBuffer::Create(), CreateGlyphAtlas(), impeller::GlyphAtlas::kAlphaBitmap, impeller::TypographerContextSkia::Make(), and impeller::MakeTextFrameFromTextBlobSkia().

◆ TEST_P() [447/454]

impeller::testing::TEST_P ( TypographerTest  ,
GlyphAtlasTextureIsRecycledIfUnchanged   
)

Definition at line 253 of file typographer_unittests.cc.

253  {
254  auto host_buffer = HostBuffer::Create(GetContext()->GetResourceAllocator());
255  auto context = TypographerContextSkia::Make();
256  auto atlas_context =
257  context->CreateGlyphAtlasContext(GlyphAtlas::Type::kAlphaBitmap);
258  ASSERT_TRUE(context && context->IsValid());
259  SkFont sk_font = flutter::testing::CreateTestFontOfSize(12);
260  auto blob = SkTextBlob::MakeFromString("spooky 1", sk_font);
261  ASSERT_TRUE(blob);
262  auto atlas =
263  CreateGlyphAtlas(*GetContext(), context.get(), *host_buffer,
264  GlyphAtlas::Type::kAlphaBitmap, 1.0f, atlas_context,
266  auto old_packer = atlas_context->GetRectPacker();
267 
268  ASSERT_NE(atlas, nullptr);
269  ASSERT_NE(atlas->GetTexture(), nullptr);
270  ASSERT_EQ(atlas, atlas_context->GetGlyphAtlas());
271 
272  auto* first_texture = atlas->GetTexture().get();
273 
274  // Now create a new glyph atlas with a nearly identical blob.
275 
276  auto blob2 = SkTextBlob::MakeFromString("spooky 2", sk_font);
277  auto next_atlas =
278  CreateGlyphAtlas(*GetContext(), context.get(), *host_buffer,
279  GlyphAtlas::Type::kAlphaBitmap, 1.0f, atlas_context,
281  ASSERT_EQ(atlas, next_atlas);
282  auto* second_texture = next_atlas->GetTexture().get();
283 
284  auto new_packer = atlas_context->GetRectPacker();
285 
286  ASSERT_EQ(second_texture, first_texture);
287  ASSERT_EQ(old_packer, new_packer);
288 }

References impeller::HostBuffer::Create(), CreateGlyphAtlas(), impeller::GlyphAtlas::kAlphaBitmap, impeller::TypographerContextSkia::Make(), and impeller::MakeTextFrameFromTextBlobSkia().

◆ TEST_P() [448/454]

impeller::testing::TEST_P ( TypographerTest  ,
GlyphAtlasTextureWillGrowTilMaxTextureSize   
)

Definition at line 419 of file typographer_unittests.cc.

419  {
420  if (GetBackend() == PlaygroundBackend::kOpenGLES) {
421  GTEST_SKIP() << "Atlas growth isn't supported for OpenGLES currently.";
422  }
423 
424  auto host_buffer = HostBuffer::Create(GetContext()->GetResourceAllocator());
425  auto context = TypographerContextSkia::Make();
426  auto atlas_context =
427  context->CreateGlyphAtlasContext(GlyphAtlas::Type::kAlphaBitmap);
428  ASSERT_TRUE(context && context->IsValid());
429  SkFont sk_font = flutter::testing::CreateTestFontOfSize(12);
430  auto blob = SkTextBlob::MakeFromString("A", sk_font);
431  ASSERT_TRUE(blob);
432  auto atlas =
433  CreateGlyphAtlas(*GetContext(), context.get(), *host_buffer,
434  GlyphAtlas::Type::kAlphaBitmap, 1.0f, atlas_context,
436  // Continually append new glyphs until the glyph size grows to the maximum.
437  // Note that the sizes here are more or less experimentally determined, but
438  // the important expectation is that the atlas size will shrink again after
439  // growing to the maximum size.
440  constexpr ISize expected_sizes[13] = {
441  {4096, 4096}, //
442  {4096, 4096}, //
443  {4096, 8192}, //
444  {4096, 8192}, //
445  {4096, 8192}, //
446  {4096, 8192}, //
447  {4096, 16384}, //
448  {4096, 16384}, //
449  {4096, 16384}, //
450  {4096, 16384}, //
451  {4096, 16384}, //
452  {4096, 16384}, //
453  {4096, 4096} // Shrinks!
454  };
455 
456  SkFont sk_font_small = flutter::testing::CreateTestFontOfSize(10);
457 
458  for (int i = 0; i < 13; i++) {
459  SkTextBlobBuilder builder;
460 
461  auto add_char = [&](const SkFont& sk_font, char c) {
462  int count = sk_font.countText(&c, 1, SkTextEncoding::kUTF8);
463  auto buffer = builder.allocRunPos(sk_font, count);
464  sk_font.textToGlyphs(&c, 1, SkTextEncoding::kUTF8, buffer.glyphs, count);
465  sk_font.getPos(buffer.glyphs, count, buffer.points(), {0, 0});
466  };
467 
468  SkFont sk_font = flutter::testing::CreateTestFontOfSize(50 + i);
469  add_char(sk_font, 'A');
470  add_char(sk_font_small, 'B');
471  auto blob = builder.make();
472 
473  atlas =
474  CreateGlyphAtlas(*GetContext(), context.get(), *host_buffer,
475  GlyphAtlas::Type::kAlphaBitmap, 50 + i, atlas_context,
477  ASSERT_TRUE(!!atlas);
478  EXPECT_EQ(atlas->GetTexture()->GetTextureDescriptor().size,
479  expected_sizes[i]);
480  }
481 
482  // The final atlas should contain both the "A" glyph (which was not present
483  // in the previous atlas) and the "B" glyph (which existed in the previous
484  // atlas).
485  ASSERT_EQ(atlas->GetGlyphCount(), 2u);
486 }

References impeller::HostBuffer::Create(), CreateGlyphAtlas(), impeller::GlyphAtlas::kAlphaBitmap, impeller::kOpenGLES, impeller::TypographerContextSkia::Make(), and impeller::MakeTextFrameFromTextBlobSkia().

◆ TEST_P() [449/454]

impeller::testing::TEST_P ( TypographerTest  ,
GlyphAtlasWithLotsOfdUniqueGlyphSize   
)

Definition at line 206 of file typographer_unittests.cc.

206  {
207  auto host_buffer = HostBuffer::Create(GetContext()->GetResourceAllocator());
208  auto context = TypographerContextSkia::Make();
209  auto atlas_context =
210  context->CreateGlyphAtlasContext(GlyphAtlas::Type::kAlphaBitmap);
211  ASSERT_TRUE(context && context->IsValid());
212 
213  const char* test_string =
214  "QWERTYUIOPASDFGHJKLZXCVBNMqewrtyuiopasdfghjklzxcvbnm,.<>[]{};':"
215  "2134567890-=!@#$%^&*()_+"
216  "œ∑´®†¥¨ˆøπ““‘‘åß∂ƒ©˙∆˚¬…æ≈ç√∫˜µ≤≥≥≥≥÷¡™£¢∞§¶•ªº–≠⁄€‹›fifl‡°·‚—±Œ„´‰Á¨Ø∏”’/"
217  "* Í˝ */¸˛Ç◊ı˜Â¯˘¿";
218 
219  SkFont sk_font = flutter::testing::CreateTestFontOfSize(12);
220  auto blob = SkTextBlob::MakeFromString(test_string, sk_font);
221  ASSERT_TRUE(blob);
222 
223  FontGlyphMap font_glyph_map;
224  size_t size_count = 8;
225  for (size_t index = 0; index < size_count; index += 1) {
226  MakeTextFrameFromTextBlobSkia(blob)->CollectUniqueFontGlyphPairs(
227  font_glyph_map, 0.6 * index, {0, 0}, {});
228  };
229  auto atlas =
230  context->CreateGlyphAtlas(*GetContext(), GlyphAtlas::Type::kAlphaBitmap,
231  *host_buffer, atlas_context, font_glyph_map);
232  ASSERT_NE(atlas, nullptr);
233  ASSERT_NE(atlas->GetTexture(), nullptr);
234 
235  std::set<uint16_t> unique_glyphs;
236  std::vector<uint16_t> total_glyphs;
237  atlas->IterateGlyphs([&](const ScaledFont& scaled_font,
238  const SubpixelGlyph& glyph, const Rect& rect) {
239  unique_glyphs.insert(glyph.glyph.index);
240  total_glyphs.push_back(glyph.glyph.index);
241  return true;
242  });
243 
244  // These numbers may be different due to subpixel positions.
245  EXPECT_LE(unique_glyphs.size() * size_count, atlas->GetGlyphCount());
246  EXPECT_EQ(total_glyphs.size(), atlas->GetGlyphCount());
247 
248  EXPECT_TRUE(atlas->GetGlyphCount() > 0);
249  EXPECT_TRUE(atlas->GetTexture()->GetSize().width > 0);
250  EXPECT_TRUE(atlas->GetTexture()->GetSize().height > 0);
251 }

References impeller::HostBuffer::Create(), impeller::SubpixelGlyph::glyph, impeller::Glyph::index, impeller::GlyphAtlas::kAlphaBitmap, impeller::TypographerContextSkia::Make(), and impeller::MakeTextFrameFromTextBlobSkia().

◆ TEST_P() [450/454]

impeller::testing::TEST_P ( TypographerTest  ,
GlyphAtlasWithOddUniqueGlyphSize   
)

Definition at line 159 of file typographer_unittests.cc.

159  {
160  auto context = TypographerContextSkia::Make();
161  auto atlas_context =
162  context->CreateGlyphAtlasContext(GlyphAtlas::Type::kAlphaBitmap);
163  auto host_buffer = HostBuffer::Create(GetContext()->GetResourceAllocator());
164  ASSERT_TRUE(context && context->IsValid());
165  SkFont sk_font = flutter::testing::CreateTestFontOfSize(12);
166  auto blob = SkTextBlob::MakeFromString("AGH", sk_font);
167  ASSERT_TRUE(blob);
168  auto atlas =
169  CreateGlyphAtlas(*GetContext(), context.get(), *host_buffer,
170  GlyphAtlas::Type::kAlphaBitmap, 1.0f, atlas_context,
172  ASSERT_NE(atlas, nullptr);
173  ASSERT_NE(atlas->GetTexture(), nullptr);
174 
175  EXPECT_EQ(atlas->GetTexture()->GetSize().width, 4096u);
176  EXPECT_EQ(atlas->GetTexture()->GetSize().height, 1024u);
177 }

References impeller::HostBuffer::Create(), CreateGlyphAtlas(), impeller::GlyphAtlas::kAlphaBitmap, impeller::TypographerContextSkia::Make(), and impeller::MakeTextFrameFromTextBlobSkia().

◆ TEST_P() [451/454]

impeller::testing::TEST_P ( TypographerTest  ,
GlyphColorIsIgnoredForNonEmojiFonts   
)

Definition at line 324 of file typographer_unittests.cc.

324  {
325  auto host_buffer = HostBuffer::Create(GetContext()->GetResourceAllocator());
326  sk_sp<SkFontMgr> font_mgr = txt::GetDefaultFontManager();
327  sk_sp<SkTypeface> typeface =
328  font_mgr->matchFamilyStyle("Arial", SkFontStyle::Normal());
329  SkFont sk_font(typeface, 0.5f);
330 
331  auto context = TypographerContextSkia::Make();
332  auto atlas_context =
333  context->CreateGlyphAtlasContext(GlyphAtlas::Type::kColorBitmap);
334 
335  // Create two frames with the same character and a different color, but as a
336  // non-emoji font the text frame constructor will ignore it.
337  auto frame =
338  MakeTextFrameFromTextBlobSkia(SkTextBlob::MakeFromString("A", sk_font));
339  auto frame_2 =
340  MakeTextFrameFromTextBlobSkia(SkTextBlob::MakeFromString("A", sk_font));
341  auto properties = {
342  GlyphProperties{},
343  GlyphProperties{},
344  };
345 
346  auto next_atlas =
347  CreateGlyphAtlas(*GetContext(), context.get(), *host_buffer,
348  GlyphAtlas::Type::kColorBitmap, 1.0f, atlas_context,
349  {frame, frame_2}, properties);
350 
351  EXPECT_EQ(next_atlas->GetGlyphCount(), 1u);
352 }

References impeller::HostBuffer::Create(), CreateGlyphAtlas(), impeller::GlyphAtlas::kColorBitmap, impeller::TypographerContextSkia::Make(), and impeller::MakeTextFrameFromTextBlobSkia().

◆ TEST_P() [452/454]

impeller::testing::TEST_P ( TypographerTest  ,
GlyphColorIsPartOfCacheKey   
)

Definition at line 290 of file typographer_unittests.cc.

290  {
291  auto host_buffer = HostBuffer::Create(GetContext()->GetResourceAllocator());
292 #if FML_OS_MACOSX
293  auto mapping = flutter::testing::OpenFixtureAsSkData("Apple Color Emoji.ttc");
294 #else
295  auto mapping = flutter::testing::OpenFixtureAsSkData("NotoColorEmoji.ttf");
296 #endif
297  ASSERT_TRUE(mapping);
298  sk_sp<SkFontMgr> font_mgr = txt::GetDefaultFontManager();
299  SkFont emoji_font(font_mgr->makeFromData(mapping), 50.0);
300 
301  auto context = TypographerContextSkia::Make();
302  auto atlas_context =
303  context->CreateGlyphAtlasContext(GlyphAtlas::Type::kColorBitmap);
304 
305  // Create two frames with the same character and a different color, expect
306  // that it adds a character.
307  auto frame = MakeTextFrameFromTextBlobSkia(
308  SkTextBlob::MakeFromString("😂", emoji_font));
309  auto frame_2 = MakeTextFrameFromTextBlobSkia(
310  SkTextBlob::MakeFromString("😂", emoji_font));
311  auto properties = {
312  GlyphProperties{.color = Color::Red()},
313  GlyphProperties{.color = Color::Blue()},
314  };
315 
316  auto next_atlas =
317  CreateGlyphAtlas(*GetContext(), context.get(), *host_buffer,
318  GlyphAtlas::Type::kColorBitmap, 1.0f, atlas_context,
319  {frame, frame_2}, properties);
320 
321  EXPECT_EQ(next_atlas->GetGlyphCount(), 2u);
322 }

References impeller::Color::Blue(), impeller::GlyphProperties::color, impeller::HostBuffer::Create(), CreateGlyphAtlas(), impeller::GlyphAtlas::kColorBitmap, impeller::TypographerContextSkia::Make(), impeller::MakeTextFrameFromTextBlobSkia(), and impeller::Color::Red().

◆ TEST_P() [453/454]

impeller::testing::TEST_P ( TypographerTest  ,
LazyAtlasTracksColor   
)

Definition at line 120 of file typographer_unittests.cc.

120  {
121  auto host_buffer = HostBuffer::Create(GetContext()->GetResourceAllocator());
122 #if FML_OS_MACOSX
123  auto mapping = flutter::testing::OpenFixtureAsSkData("Apple Color Emoji.ttc");
124 #else
125  auto mapping = flutter::testing::OpenFixtureAsSkData("NotoColorEmoji.ttf");
126 #endif
127  ASSERT_TRUE(mapping);
128  sk_sp<SkFontMgr> font_mgr = txt::GetDefaultFontManager();
129  SkFont emoji_font(font_mgr->makeFromData(mapping), 50.0);
130  SkFont sk_font = flutter::testing::CreateTestFontOfSize(12);
131 
132  auto blob = SkTextBlob::MakeFromString("hello", sk_font);
133  ASSERT_TRUE(blob);
134  auto frame = MakeTextFrameFromTextBlobSkia(blob);
135 
136  ASSERT_FALSE(frame->GetAtlasType() == GlyphAtlas::Type::kColorBitmap);
137 
138  LazyGlyphAtlas lazy_atlas(TypographerContextSkia::Make());
139 
140  lazy_atlas.AddTextFrame(*frame, 1.0f, {0, 0}, {});
141 
143  SkTextBlob::MakeFromString("😀 ", emoji_font));
144 
145  ASSERT_TRUE(frame->GetAtlasType() == GlyphAtlas::Type::kColorBitmap);
146 
147  lazy_atlas.AddTextFrame(*frame, 1.0f, {0, 0}, {});
148 
149  // Creates different atlases for color and red bitmap.
150  auto color_atlas = lazy_atlas.CreateOrGetGlyphAtlas(
151  *GetContext(), *host_buffer, GlyphAtlas::Type::kColorBitmap);
152 
153  auto bitmap_atlas = lazy_atlas.CreateOrGetGlyphAtlas(
154  *GetContext(), *host_buffer, GlyphAtlas::Type::kAlphaBitmap);
155 
156  ASSERT_FALSE(color_atlas == bitmap_atlas);
157 }

References impeller::LazyGlyphAtlas::AddTextFrame(), impeller::HostBuffer::Create(), impeller::LazyGlyphAtlas::CreateOrGetGlyphAtlas(), impeller::GlyphAtlas::kAlphaBitmap, impeller::GlyphAtlas::kColorBitmap, impeller::TypographerContextSkia::Make(), and impeller::MakeTextFrameFromTextBlobSkia().

◆ TEST_P() [454/454]

impeller::testing::TEST_P ( TypographerTest  ,
RectanglePackerAddsNonoverlapingRectangles   
)

Definition at line 354 of file typographer_unittests.cc.

354  {
355  auto packer = RectanglePacker::Factory(200, 100);
356  ASSERT_NE(packer, nullptr);
357  ASSERT_EQ(packer->PercentFull(), 0);
358 
359  const SkIRect packer_area = SkIRect::MakeXYWH(0, 0, 200, 100);
360 
361  IPoint16 first_output = {-1, -1}; // Fill with sentinel values
362  ASSERT_TRUE(packer->AddRect(20, 20, &first_output));
363  // Make sure the rectangle is placed such that it is inside the bounds of
364  // the packer's area.
365  const SkIRect first_rect =
366  SkIRect::MakeXYWH(first_output.x(), first_output.y(), 20, 20);
367  ASSERT_TRUE(SkIRect::Intersects(packer_area, first_rect));
368 
369  // Initial area was 200 x 100 = 20_000
370  // We added 20x20 = 400. 400 / 20_000 == 0.02 == 2%
371  ASSERT_TRUE(flutter::testing::NumberNear(packer->PercentFull(), 0.02));
372 
373  IPoint16 second_output = {-1, -1};
374  ASSERT_TRUE(packer->AddRect(140, 90, &second_output));
375  const SkIRect second_rect =
376  SkIRect::MakeXYWH(second_output.x(), second_output.y(), 140, 90);
377  // Make sure the rectangle is placed such that it is inside the bounds of
378  // the packer's area but not in the are of the first rectangle.
379  ASSERT_TRUE(SkIRect::Intersects(packer_area, second_rect));
380  ASSERT_FALSE(SkIRect::Intersects(first_rect, second_rect));
381 
382  // We added another 90 x 140 = 12_600 units, now taking us to 13_000
383  // 13_000 / 20_000 == 0.65 == 65%
384  ASSERT_TRUE(flutter::testing::NumberNear(packer->PercentFull(), 0.65));
385 
386  // There's enough area to add this rectangle, but no space big enough for
387  // the 50 units of width.
388  IPoint16 output;
389  ASSERT_FALSE(packer->AddRect(50, 50, &output));
390  // Should be unchanged.
391  ASSERT_TRUE(flutter::testing::NumberNear(packer->PercentFull(), 0.65));
392 
393  packer->Reset();
394  // Should be empty now.
395  ASSERT_EQ(packer->PercentFull(), 0);
396 }

References impeller::RectanglePacker::Factory(), NumberNear(), impeller::IPoint16::x(), and impeller::IPoint16::y().

◆ toColor()

flutter::DlColor impeller::testing::toColor ( const float *  components)

Definition at line 41 of file dl_unittests.cc.

41  {
42  return flutter::DlColor(Color::ToIColor(
43  Color(components[0], components[1], components[2], components[3])));
44 }

References impeller::Color::ToIColor().

Referenced by TEST_P().

Variable Documentation

◆ golden_cubic_and_quad_points

std::vector<Point> impeller::testing::golden_cubic_and_quad_points

Definition at line 16 of file golden_paths.h.

◆ kFontFixture

constexpr std::string_view impeller::testing::kFontFixture
staticconstexpr
Initial value:
=
"NotoColorEmoji.ttf"

Definition at line 281 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 484 of file aiks_dl_blur_unittests.cc.

impeller::testing::kMagicFailingAllocation
static constexpr const size_t kMagicFailingAllocation
Definition: host_buffer_unittests.cc:166
impeller::ISize
ISize64 ISize
Definition: size.h:140
_BLEND_MODE_RESULT_CHECK
#define _BLEND_MODE_RESULT_CHECK(blend_mode)
Definition: geometry_unittests.cc:1640
NumberNear
bool NumberNear(double a, double b)
Definition: geometry_asserts.h:18
impeller::testing::RenderTextInCanvasSkia
bool RenderTextInCanvasSkia(const std::shared_ptr< Context > &context, DisplayListBuilder &canvas, const std::string &text, const std::string_view &font_fixture, const TextRenderOptions &options={})
Definition: aiks_dl_text_unittests.cc:41
ASSERT_COLOR_NEAR
#define ASSERT_COLOR_NEAR(a, b)
Definition: geometry_asserts.h:192
impeller::kFloat
@ kFloat
Definition: runtime_types.h:23
impeller::OptionsFromPass
ContentContextOptions OptionsFromPass(const RenderPass &pass)
Definition: contents.cc:19
impeller::k1OverSqrt2
constexpr float k1OverSqrt2
Definition: constants.h:50
impeller::testing::CompareFunctionUI
static const CompareFunctionUIData & CompareFunctionUI()
Definition: renderer_unittests.cc:1184
impeller::MyMask
Mask< MyMaskBits > MyMask
Definition: base_unittests.cc:20
impeller::BlendModeToString
const char * BlendModeToString(BlendMode blend_mode)
Definition: color.cc:47
impeller::PipelineCacheDataPersist
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...
Definition: pipeline_cache_data_vk.cc:16
polyline
const Path::Polyline & polyline
Definition: stroke_path_geometry.cc:296
impeller::TPoint::y
Type y
Definition: point.h:31
impeller::PixelFormatToString
constexpr const char * PixelFormatToString(PixelFormat format)
Definition: formats.h:140
impeller::Scalar
float Scalar
Definition: scalar.h:18
impeller::testing::CreateTestCanvas
std::unique_ptr< Canvas > CreateTestCanvas(ContentContext &context, std::optional< Rect > cull_rect=std::nullopt)
Definition: canvas_unittests.cc:13
impeller::skia_conversions::IsNearlySimpleRRect
bool IsNearlySimpleRRect(const SkRRect &rr)
Like SkRRect.isSimple, but allows the corners to differ by kEhCloseEnough.
Definition: skia_conversions.cc:21
impeller::TPoint::Ceil
constexpr TPoint Ceil() const
Definition: point.h:196
impeller::testing::CompareFunctionUIData::IndexOf
int IndexOf(CompareFunction func) const
Definition: renderer_unittests.cc:1167
impeller::FontGlyphMap
std::unordered_map< ScaledFont, std::unordered_set< SubpixelGlyph, SubpixelGlyph::Hash, SubpixelGlyph::Equal >, ScaledFont::Hash, ScaledFont::Equal > FontGlyphMap
Definition: font_glyph_pair.h:108
uvs
Quad uvs
Definition: gaussian_blur_filter_contents.cc:204
impeller::KiloBytes
AllocationSize< 1 '000u > KiloBytes
Definition: allocation_size.h:153
impeller::skia_conversions::ConvertStops
void ConvertStops(const flutter::DlGradientColorSourceBase *gradient, std::vector< Color > &colors, std::vector< float > &stops)
Convert display list colors + stops into impeller colors and stops, taking care to ensure that the st...
Definition: skia_conversions.cc:144
impeller::testing::swap_nan
static constexpr Point swap_nan(const Point &point, int index)
Definition: rect_unittests.cc:1336
impeller::skia_conversions::ToSize
Size ToSize(const SkPoint &point)
Definition: skia_conversions.cc:102
impeller::BlendMode
BlendMode
Definition: color.h:58
impeller::testing::CreateMappingFromString
static std::shared_ptr< fml::Mapping > CreateMappingFromString(std::string p_string)
Definition: shader_archive_unittests.cc:15
impeller::TPoint::Lerp
constexpr TPoint Lerp(const TPoint &p, Scalar t) const
Definition: point.h:236
impeller::kEhCloseEnough
constexpr float kEhCloseEnough
Definition: constants.h:56
impeller::MebiBytes
AllocationSize< 1 '024u *1 '024u > MebiBytes
Definition: allocation_size.h:158
data
std::shared_ptr< const fml::Mapping > data
Definition: texture_gles.cc:63
font_size
SkScalar font_size
Definition: dl_golden_blur_unittests.cc:23
impeller::TextureDescriptor::format
PixelFormat format
Definition: texture_descriptor.h:41
impeller::TPoint::Min
constexpr TPoint Min(const TPoint &p) const
Definition: point.h:186
impeller::ComputeSaveLayerCoverage
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.
Definition: save_layer_utils.cc:16
impeller::TPoint::Round
static constexpr TPoint Round(const TPoint< U > &other)
Definition: point.h:49
impeller::Vector2
Point Vector2
Definition: point.h:331
EXPECT_POINT_NEAR
#define EXPECT_POINT_NEAR(a, b)
Definition: geometry_asserts.h:205
impeller::skia_conversions::ToMatrix
Matrix ToMatrix(const SkMatrix &m)
Definition: skia_conversions.cc:193
MatrixNear
inline ::testing::AssertionResult MatrixNear(impeller::Matrix a, impeller::Matrix b)
Definition: geometry_asserts.h:56
impeller::kPi
constexpr float kPi
Definition: constants.h:26
impeller::testing::CanRenderRadialGradientWithDithering
static void CanRenderRadialGradientWithDithering(AiksTest *aiks_test)
Definition: aiks_dl_gradient_unittests.cc:124
impeller::testing::flip_lrtb
static constexpr R flip_lrtb(R rect)
Definition: rect_unittests.cc:1322
impeller::CreateTextureFromDrawableFuture
std::shared_ptr< TextureMTL > CreateTextureFromDrawableFuture(TextureDescriptor desc, const std::shared_future< id< CAMetalDrawable >> &drawble_future)
Create a TextureMTL from a deferred drawable.
Definition: lazy_drawable_holder.mm:41
impeller::kSampledImage
@ kSampledImage
Definition: runtime_types.h:24
impeller::skia_conversions::ToColor
Color ToColor(const flutter::DlColor &color)
Definition: skia_conversions.cc:106
impeller::UintPoint32
TPoint< uint32_t > UintPoint32
Definition: point.h:330
padding
Vector2 padding
The halo padding in source space.
Definition: gaussian_blur_filter_contents.cc:85
buffer_view
BufferView buffer_view
Definition: blit_command_gles.cc:128
impeller::Size
TSize< Scalar > Size
Definition: size.h:137
impeller::GetMaliVersion
MaliGPU GetMaliVersion(std::string_view version)
Definition: driver_info_vk.cc:122
impeller::StorageMode::kHostVisible
@ kHostVisible
ASSERT_POINT_NEAR
#define ASSERT_POINT_NEAR(a, b)
Definition: geometry_asserts.h:193
impeller::kGaussianBlurMaxKernelSize
static constexpr int32_t kGaussianBlurMaxKernelSize
Definition: gaussian_blur_filter_contents.h:17
impeller::CreateMappingFromAllocation
std::shared_ptr< fml::Mapping > CreateMappingFromAllocation(const std::shared_ptr< Allocation > &allocation)
Creates a mapping from allocation.
Definition: allocation.cc:99
ASSERT_VECTOR4_NEAR
#define ASSERT_VECTOR4_NEAR(a, b)
Definition: geometry_asserts.h:195
impeller::PlaygroundBackendToRuntimeStageBackend
constexpr RuntimeStageBackend PlaygroundBackendToRuntimeStageBackend(PlaygroundBackend backend)
Definition: playground.h:32
stroke_width
const Scalar stroke_width
Definition: stroke_path_geometry.cc:297
impeller::GibiBytes
AllocationSize< 1 '024u *1 '024u *1 '024u > GibiBytes
Definition: allocation_size.h:159
offset
SeparatedVector2 offset
Definition: stroke_path_geometry.cc:304
impeller::MoveTo
void MoveTo(PathBuilder *builder, Scalar x, Scalar y)
Definition: tessellator.cc:20
EXPECT_RECT_NEAR
#define EXPECT_RECT_NEAR(a, b)
Definition: geometry_asserts.h:203
impeller::GetDrawableDeferred
std::shared_future< id< CAMetalDrawable > > GetDrawableDeferred(CAMetalLayer *layer)
Create a deferred drawable from a CAMetalLayer.
Definition: lazy_drawable_holder.mm:23
impeller::TPoint::Floor
constexpr TPoint Floor() const
Definition: point.h:194
impeller::skia_conversions::ToBlendMode
BlendMode ToBlendMode(flutter::DlBlendMode mode)
Definition: skia_conversions.cc:204
impeller::ToShaderStage
constexpr ShaderStage ToShaderStage(RuntimeShaderStage stage)
Definition: shader_types.h:29
impeller::kPiOver2
constexpr float kPiOver2
Definition: constants.h:32
impeller::TRect::Shift
constexpr TRect< T > Shift(T dx, T dy) const
Returns a new rectangle translated by the given offset.
Definition: rect.h:596
impeller::PixelFormat
PixelFormat
The Pixel formats supported by Impeller. The naming convention denotes the usage of the component,...
Definition: formats.h:99
ASSERT_RECT_NEAR
#define ASSERT_RECT_NEAR(a, b)
Definition: geometry_asserts.h:191
impeller::MakeTextFrameSTB
std::shared_ptr< TextFrame > MakeTextFrameSTB(const std::shared_ptr< TypefaceSTB > &typeface_stb, Font::Metrics metrics, const std::string &text)
Definition: text_frame_stb.cc:11
impeller::MinMagFilter::kNearest
@ kNearest
Select nearest to the sample point. Most widely supported.
impeller::kPhi
constexpr float kPhi
Definition: constants.h:53
impeller::VS
SolidFillVertexShader VS
Definition: stroke_path_geometry.cc:16
impeller::OptionsFromPassAndEntity
ContentContextOptions OptionsFromPassAndEntity(const RenderPass &pass, const Entity &entity)
Definition: contents.cc:34
impeller::saturated::distance
SI distance
Definition: saturated_math.h:57
impeller::testing::toColor
flutter::DlColor toColor(const float *components)
Definition: dl_unittests.cc:41
impeller::testing::DoGradientOvalStrokeMaskBlur
sk_sp< flutter::DisplayList > DoGradientOvalStrokeMaskBlur(Vector2 content_Scale, Scalar sigma, DlBlurStyle style)
Definition: aiks_dl_blur_unittests.cc:63
impeller::ToSamplerDescriptor
static impeller::SamplerDescriptor ToSamplerDescriptor(const flutter::DlFilterMode options)
Definition: dl_dispatcher.cc:118
impeller::Point
TPoint< Scalar > Point
Definition: point.h:327
impeller::k2Pi
constexpr float k2Pi
Definition: constants.h:29
impeller::Quad
std::array< Point, 4 > Quad
Definition: point.h:332
impeller::KibiBytes
AllocationSize< 1 '024u > KibiBytes
Definition: allocation_size.h:157
impeller::testing::CompareFunctionUIData::FunctionOf
CompareFunction FunctionOf(int index) const
Definition: renderer_unittests.cc:1177
impeller::testing::RGBToYUV
static Vector3 RGBToYUV(Vector3 rgb, YUVColorSpace yuv_color_space)
Definition: entity_unittests.cc:1642
impeller::MipFilter
MipFilter
Options for selecting and filtering between mipmap levels.
Definition: formats.h:425
impeller::testing::flip_lr
static constexpr R flip_lr(R rect)
Definition: rect_unittests.cc:1310
impeller::SPrintF
std::string SPrintF(const char *format,...)
Definition: strings.cc:12
EXPECT_VECTOR3_NEAR
#define EXPECT_VECTOR3_NEAR(a, b)
Definition: geometry_asserts.h:206
transform
Matrix transform
Definition: gaussian_blur_filter_contents.cc:213
impeller::testing::GetBlendModeSelection
static BlendModeSelection GetBlendModeSelection()
Definition: aiks_dl_blend_unittests.cc:45
impeller::IPoint32
TPoint< int32_t > IPoint32
Definition: point.h:329
impeller::ScalarToHalf
constexpr InternalHalf ScalarToHalf(Scalar f)
Convert a scalar to a half precision float.
Definition: half.h:32
impeller::MinMagFilter::kLinear
@ kLinear
impeller::TPoint::Max
constexpr TPoint Max(const TPoint &p) const
Definition: point.h:190
type
GLenum type
Definition: blit_command_gles.cc:127
impeller::Matrix::MakeColumn
static constexpr Matrix MakeColumn(Scalar m0, Scalar m1, Scalar m2, Scalar m3, Scalar m4, Scalar m5, Scalar m6, Scalar m7, Scalar m8, Scalar m9, Scalar m10, Scalar m11, Scalar m12, Scalar m13, Scalar m14, Scalar m15)
Definition: matrix.h:69
impeller::MinMagFilter
MinMagFilter
Describes how the texture should be sampled when the texture is being shrunk (minified) or expanded (...
Definition: formats.h:415
impeller::testing::CreateTestYUVTextures
static std::vector< std::shared_ptr< Texture > > CreateTestYUVTextures(Context *context, YUVColorSpace yuv_color_space)
Definition: entity_unittests.cc:1659
_BLEND_MODE_NAME_CHECK
#define _BLEND_MODE_NAME_CHECK(blend_mode)
Definition: geometry_unittests.cc:1658
impeller::Rect
TRect< Scalar > Rect
Definition: rect.h:776
ASSERT_MATRIX_NEAR
#define ASSERT_MATRIX_NEAR(a, b)
Definition: geometry_asserts.h:189
impeller::testing::CreateStringFromMapping
const std::string CreateStringFromMapping(const fml::Mapping &mapping)
Definition: shader_archive_unittests.cc:23
impeller::TextureUsageMask
Mask< TextureUsage > TextureUsageMask
Definition: formats.h:308
impeller::CreateGradientBuffer
GradientData CreateGradientBuffer(const std::vector< Color > &colors, const std::vector< Scalar > &stops)
Populate a vector with the interpolated color bytes for the linear gradient described by colors and s...
Definition: gradient.cc:20
impeller::kStruct
@ kStruct
Definition: runtime_types.h:25
impeller::skia_conversions::ToPoint
Point ToPoint(const SkPoint &point)
Definition: skia_conversions.cc:98
impeller::testing::CanRenderConicalGradientWithDithering
static void CanRenderConicalGradientWithDithering(AiksTest *aiks_test)
Definition: aiks_dl_gradient_unittests.cc:167
IMPELLER_FOR_EACH_BLEND_MODE
#define IMPELLER_FOR_EACH_BLEND_MODE(V)
Definition: color.h:19
IMPELLER_RAND
#define IMPELLER_RAND
Definition: gaussian_blur_filter_contents_unittests.cc:19
impeller::MakeTextFrameFromTextBlobSkia
std::shared_ptr< TextFrame > MakeTextFrameFromTextBlobSkia(const sk_sp< SkTextBlob > &blob)
Definition: text_frame_skia.cc:42
impeller::ContentContextOptions::primitive_type
PrimitiveType primitive_type
Definition: content_context.h:311
impeller::ToMTLPixelFormat
constexpr MTLPixelFormat ToMTLPixelFormat(PixelFormat format)
Definition: formats_mtl.h:76
ASSERT_QUATERNION_NEAR
#define ASSERT_QUATERNION_NEAR(a, b)
Definition: geometry_asserts.h:190
impeller::GenerateBlurInfo
KernelSamples GenerateBlurInfo(BlurParameters parameters)
Definition: gaussian_blur_filter_contents.cc:886
impeller::Close
void Close(PathBuilder *builder)
Definition: tessellator.cc:38
impeller::TextureDescriptor::size
ISize size
Definition: texture_descriptor.h:42
VALIDATION_LOG
#define VALIDATION_LOG
Definition: validation.h:91
impeller::MegaBytes
AllocationSize< 1 '000u *1 '000u > MegaBytes
Definition: allocation_size.h:154
impeller::LineTo
void LineTo(PathBuilder *builder, Scalar x, Scalar y)
Definition: tessellator.cc:24
impeller::Join
Join
Definition: path.h:24
impeller::MipFilter::kBase
@ kBase
The texture is sampled as if it only had a single mipmap level.
RectNear
inline ::testing::AssertionResult RectNear(impeller::Rect a, impeller::Rect b)
Definition: geometry_asserts.h:89
impeller::DrawPlaygroundPoint
Point DrawPlaygroundPoint(PlaygroundPoint &point)
Definition: widgets.cc:9
impeller::testing::CanRenderLinearGradientWithDithering
static void CanRenderLinearGradientWithDithering(AiksTest *aiks_test)
Definition: aiks_dl_gradient_unittests.cc:104
BLEND_MODE_TUPLE
#define BLEND_MODE_TUPLE(blend_mode)
Definition: aiks_dl_blend_unittests.cc:38
impeller::IPoint
TPoint< int64_t > IPoint
Definition: point.h:328
impeller::PipelineCacheDataRetrieve
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...
Definition: pipeline_cache_data_vk.cc:58
impeller::MyMaskBits
MyMaskBits
Definition: base_unittests.cc:13
ASSERT_VECTOR3_NEAR
#define ASSERT_VECTOR3_NEAR(a, b)
Definition: geometry_asserts.h:194
impeller::saturated::b
SI b
Definition: saturated_math.h:87
impeller::testing::kFontFixture
static constexpr std::string_view kFontFixture
Definition: aiks_dl_text_unittests.cc:281
impeller::MipFilter::kLinear
@ kLinear
Sample from the two nearest mip levels and linearly interpolate.
impeller::GetAdrenoVersion
AdrenoGPU GetAdrenoVersion(std::string_view version)
Definition: driver_info_vk.cc:108
scale
const Scalar scale
Definition: stroke_path_geometry.cc:301
blur_radius
Vector2 blur_radius
Blur radius in source pixels based on scaled_sigma.
Definition: gaussian_blur_filter_contents.cc:83
impeller::ScalarNearlyEqual
constexpr bool ScalarNearlyEqual(Scalar x, Scalar y, Scalar tolerance=kEhCloseEnough)
Definition: scalar.h:35
impeller::YUVColorSpace
YUVColorSpace
Definition: color.h:54
impeller::LerpHackKernelSamples
GaussianBlurPipeline::FragmentShader::KernelSamples LerpHackKernelSamples(KernelSamples parameters)
Definition: gaussian_blur_filter_contents.cc:933
impeller::testing::CreateGlyphAtlas
static std::shared_ptr< GlyphAtlas > CreateGlyphAtlas(Context &context, const TypographerContext *typographer_context, HostBuffer &host_buffer, GlyphAtlas::Type type, Scalar scale, const std::shared_ptr< GlyphAtlasContext > &atlas_context, const std::vector< std::shared_ptr< TextFrame >> &frames, const std::vector< GlyphProperties > &properties)
Definition: typographer_unittests.cc:46
impeller::TPoint::Rotate
constexpr TPoint Rotate(const Radians &angle) const
Definition: point.h:226
impeller::SampleCount::kCount1
@ kCount1
impeller::IRect
IRect64 IRect
Definition: rect.h:779
color
DlColor color
Definition: dl_golden_blur_unittests.cc:24
impeller::DisplayListToTexture
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.
Definition: dl_dispatcher.cc:1195
impeller::TextureDescriptor::storage_mode
StorageMode storage_mode
Definition: texture_descriptor.h:39
impeller::TPoint::GetDistance
constexpr Type GetDistance(const TPoint &p) const
Definition: point.h:200
impeller::TextureDescriptor
A lightweight object that describes the attributes of a texture that can then used an allocator to cr...
Definition: texture_descriptor.h:38
impeller::testing::RenderTextInCanvasSTB
bool RenderTextInCanvasSTB(const std::shared_ptr< Context > &context, DisplayListBuilder &canvas, const std::string &text, const std::string &font_fixture, const TextRenderOptions &options={})
Definition: aiks_dl_text_unittests.cc:84
impeller::TSize::MipCount
constexpr size_t MipCount() const
Definition: size.h:115
impeller::GigaBytes
AllocationSize< 1 '000u *1 '000u *1 '000u > GigaBytes
Definition: allocation_size.h:155
impeller::TPoint::Normalize
constexpr TPoint Normalize() const
Definition: point.h:208
impeller::interop::Create
ScopedObject< Object > Create(CtorArgs &&... args)
Definition: object.h:160
impeller::testing::flip_tb
static constexpr R flip_tb(R rect)
Definition: rect_unittests.cc:1316
ASSERT_COLOR_BUFFER_NEAR
#define ASSERT_COLOR_BUFFER_NEAR(a, b)
Definition: geometry_asserts.h:198
impeller::DlScalar
flutter::DlScalar DlScalar
Definition: dl_dispatcher.h:21
impeller::testing::CanRenderSweepGradientWithDithering
static void CanRenderSweepGradientWithDithering(AiksTest *aiks_test)
Definition: aiks_dl_gradient_unittests.cc:144
impeller::kPiOver4
constexpr float kPiOver4
Definition: constants.h:35
impeller::AllocationSize::GetSize
constexpr double GetSize() const
Definition: allocation_size.h:76
impeller::Bytes
AllocationSize< 1u > Bytes
Definition: allocation_size.h:151
impeller::Cap
Cap
Definition: path.h:18
ASSERT_ARRAY_4_NEAR
#define ASSERT_ARRAY_4_NEAR(a, b)
Definition: geometry_asserts.h:197
IPLR_REQUIRES
#define IPLR_REQUIRES(...)
Definition: thread_safety.h:30
impeller::DrawPlaygroundLine
std::tuple< Point, Point > DrawPlaygroundLine(PlaygroundPoint &point_a, PlaygroundPoint &point_b)
Definition: widgets.cc:50
impeller::testing::IsBadVersionTest
bool IsBadVersionTest(std::string_view driver_name, bool qc=true)
Definition: driver_info_vk_unittests.cc:52